lifetime.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package plugin_manager
  2. import (
  3. "time"
  4. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
  5. "github.com/langgenius/dify-plugin-daemon/internal/utils/log"
  6. )
  7. func (p *PluginManager) AddPluginRegisterHandler(handler func(r plugin_entities.PluginLifetime) error) {
  8. p.pluginRegisters = append(p.pluginRegisters, handler)
  9. }
  10. func (p *PluginManager) fullDuplexLifetime(r plugin_entities.PluginFullDuplexLifetime) {
  11. identifier, err := r.Identity()
  12. if err != nil {
  13. log.Error("get plugin identity failed: %s", err.Error())
  14. return
  15. }
  16. p.m.Store(identifier.String(), r)
  17. defer p.m.Delete(identifier.String())
  18. configuration := r.Configuration()
  19. log.Info("new plugin logged in: %s", configuration.Identity())
  20. defer log.Info("plugin %s has exited", configuration.Identity())
  21. // cleanup plugin runtime state and working directory
  22. defer r.Cleanup()
  23. // stop plugin when the plugin reaches the end of its lifetime
  24. defer r.Stop()
  25. // register plugin
  26. for _, reg := range p.pluginRegisters {
  27. err := reg(r)
  28. if err != nil {
  29. log.Error("add plugin to cluster failed: %s", err.Error())
  30. return
  31. }
  32. }
  33. start_failed_times := 0
  34. // remove lifetime state after plugin if it has been stopped
  35. defer r.TriggerStop()
  36. // try at most 3 times to init environment
  37. for i := 0; i < 3; i++ {
  38. if err := r.InitEnvironment(); err != nil {
  39. log.Error("init environment failed: %s, retry in 30s", err.Error())
  40. if start_failed_times == 3 {
  41. log.Error(
  42. "init environment failed 3 times, plugin %s has been stopped",
  43. configuration.Identity(),
  44. )
  45. return
  46. }
  47. time.Sleep(30 * time.Second)
  48. start_failed_times++
  49. continue
  50. }
  51. }
  52. // TODO: launched will only be triggered when calling StartPlugin
  53. // init environment successfully
  54. // once succeed, we consider the plugin is installed successfully
  55. for !r.Stopped() {
  56. // start plugin
  57. if err := r.StartPlugin(); err != nil {
  58. if r.Stopped() {
  59. // plugin has been stopped, exit
  60. break
  61. }
  62. }
  63. // wait for plugin to stop normally
  64. c, err := r.Wait()
  65. if err == nil {
  66. <-c
  67. }
  68. // restart plugin in 5s
  69. time.Sleep(5 * time.Second)
  70. // add restart times
  71. r.AddRestarts()
  72. }
  73. }