runtime.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package entities
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "encoding/gob"
  6. "encoding/hex"
  7. "hash/fnv"
  8. "time"
  9. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
  10. )
  11. type (
  12. PluginRuntime struct {
  13. State PluginRuntimeState `json:"state"`
  14. Config plugin_entities.PluginDeclaration `json:"config"`
  15. onStopped []func() `json:"-"`
  16. }
  17. PluginRuntimeInterface interface {
  18. PluginRuntimeTimeLifeInterface
  19. PluginRuntimeSessionIOInterface
  20. PluginRuntimeDockerInterface
  21. }
  22. PluginRuntimeTimeLifeInterface interface {
  23. // returns the plugin configuration
  24. Configuration() *plugin_entities.PluginDeclaration
  25. // unique identity of the plugin
  26. Identity() (string, error)
  27. // hashed identity of the plugin
  28. HashedIdentity() (string, error)
  29. // before the plugin starts, it will call this method to initialize the environment
  30. InitEnvironment() error
  31. // start the plugin, returns errors if the plugin fails to start and hangs until the plugin stops
  32. StartPlugin() error
  33. // returns true if the plugin is stopped
  34. Stopped() bool
  35. // stop the plugin
  36. Stop()
  37. // add a function to be called when the plugin stops
  38. OnStop(func())
  39. // trigger the stop event
  40. TriggerStop()
  41. // returns the runtime state of the plugin
  42. RuntimeState() PluginRuntimeState
  43. // Update the runtime state of the plugin
  44. UpdateScheduledAt(t time.Time)
  45. // returns the checksum of the plugin
  46. Checksum() string
  47. // wait for the plugin to stop
  48. Wait() (<-chan bool, error)
  49. // returns the runtime type of the plugin
  50. Type() PluginRuntimeType
  51. // set the plugin to active
  52. SetActive()
  53. // set the plugin to launching
  54. SetLaunching()
  55. // set the plugin to restarting
  56. SetRestarting()
  57. // set the plugin to pending
  58. SetPending()
  59. // set the active time of the plugin
  60. SetActiveAt(t time.Time)
  61. // set the scheduled time of the plugin
  62. SetScheduledAt(t time.Time)
  63. // add restarts to the plugin
  64. AddRestarts()
  65. }
  66. PluginRuntimeSessionIOInterface interface {
  67. Listen(session_id string) *BytesIOListener
  68. Write(session_id string, data []byte)
  69. }
  70. PluginRuntimeDockerInterface interface {
  71. // returns the docker image and the delete function, always call the delete function when the image is no longer needed
  72. DockerImage() (string, func(), error)
  73. }
  74. )
  75. func (r *PluginRuntime) Stopped() bool {
  76. return r.State.Status == PLUGIN_RUNTIME_STATUS_STOPPED
  77. }
  78. func (r *PluginRuntime) Stop() {
  79. r.State.Status = PLUGIN_RUNTIME_STATUS_STOPPED
  80. }
  81. func (r *PluginRuntime) Configuration() *plugin_entities.PluginDeclaration {
  82. return &r.Config
  83. }
  84. func (r *PluginRuntime) Identity() (string, error) {
  85. return r.Config.Identity(), nil
  86. }
  87. func HashedIdentity(identity string) string {
  88. hash := sha256.New()
  89. hash.Write([]byte(identity))
  90. return hex.EncodeToString(hash.Sum(nil))
  91. }
  92. func (r *PluginRuntime) HashedIdentity() (string, error) {
  93. return HashedIdentity(r.Config.Identity()), nil
  94. }
  95. func (r *PluginRuntime) RuntimeState() PluginRuntimeState {
  96. return r.State
  97. }
  98. func (r *PluginRuntime) UpdateScheduledAt(t time.Time) {
  99. r.State.ScheduledAt = &t
  100. }
  101. func (r *PluginRuntime) InitState() {
  102. r.State = PluginRuntimeState{
  103. Restarts: 0,
  104. Status: PLUGIN_RUNTIME_STATUS_PENDING,
  105. ActiveAt: nil,
  106. StoppedAt: nil,
  107. Verified: false,
  108. ScheduledAt: nil,
  109. Logs: []string{},
  110. }
  111. }
  112. func (r *PluginRuntime) SetActive() {
  113. r.State.Status = PLUGIN_RUNTIME_STATUS_ACTIVE
  114. }
  115. func (r *PluginRuntime) SetLaunching() {
  116. r.State.Status = PLUGIN_RUNTIME_STATUS_LAUNCHING
  117. }
  118. func (r *PluginRuntime) SetRestarting() {
  119. r.State.Status = PLUGIN_RUNTIME_STATUS_RESTARTING
  120. }
  121. func (r *PluginRuntime) SetPending() {
  122. r.State.Status = PLUGIN_RUNTIME_STATUS_PENDING
  123. }
  124. func (r *PluginRuntime) SetActiveAt(t time.Time) {
  125. r.State.ActiveAt = &t
  126. }
  127. func (r *PluginRuntime) SetScheduledAt(t time.Time) {
  128. r.State.ScheduledAt = &t
  129. }
  130. func (r *PluginRuntime) AddRestarts() {
  131. r.State.Restarts++
  132. }
  133. func (r *PluginRuntime) OnStop(f func()) {
  134. r.onStopped = append(r.onStopped, f)
  135. }
  136. func (r *PluginRuntime) TriggerStop() {
  137. for _, f := range r.onStopped {
  138. f()
  139. }
  140. }
  141. type PluginRuntimeType string
  142. const (
  143. PLUGIN_RUNTIME_TYPE_LOCAL PluginRuntimeType = "local"
  144. PLUGIN_RUNTIME_TYPE_REMOTE PluginRuntimeType = "remote"
  145. PLUGIN_RUNTIME_TYPE_AWS PluginRuntimeType = "aws"
  146. )
  147. type PluginRuntimeState struct {
  148. Restarts int `json:"restarts"`
  149. Status string `json:"status"`
  150. AbsolutePath string `json:"absolute_path"`
  151. ActiveAt *time.Time `json:"active_at"`
  152. StoppedAt *time.Time `json:"stopped_at"`
  153. Verified bool `json:"verified"`
  154. ScheduledAt *time.Time `json:"scheduled_at"`
  155. Logs []string `json:"logs"`
  156. }
  157. func (s *PluginRuntimeState) Hash() (uint64, error) {
  158. buf := bytes.Buffer{}
  159. enc := gob.NewEncoder(&buf)
  160. err := enc.Encode(s)
  161. if err != nil {
  162. return 0, err
  163. }
  164. j := fnv.New64a()
  165. _, err = j.Write(buf.Bytes())
  166. if err != nil {
  167. return 0, err
  168. }
  169. return j.Sum64(), nil
  170. }
  171. const (
  172. PLUGIN_RUNTIME_STATUS_ACTIVE = "active"
  173. PLUGIN_RUNTIME_STATUS_LAUNCHING = "launching"
  174. PLUGIN_RUNTIME_STATUS_STOPPED = "stopped"
  175. PLUGIN_RUNTIME_STATUS_RESTARTING = "restarting"
  176. PLUGIN_RUNTIME_STATUS_PENDING = "pending"
  177. )