runtime.go 4.1 KB

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