runtime.go 4.9 KB

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