run.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package local_manager
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "sync"
  6. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager/stdio_holder"
  7. "github.com/langgenius/dify-plugin-daemon/internal/types/entities"
  8. "github.com/langgenius/dify-plugin-daemon/internal/utils/log"
  9. "github.com/langgenius/dify-plugin-daemon/internal/utils/routine"
  10. )
  11. func (r *LocalPluginRuntime) StartPlugin() error {
  12. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_LAUNCHING
  13. defer func() {
  14. r.io_identity = ""
  15. }()
  16. defer log.Info("plugin %s stopped", r.Config.Identity())
  17. // start plugin
  18. e := exec.Command("bash", "launch.sh")
  19. e.Dir = r.State.RelativePath
  20. // get writer
  21. stdin, err := e.StdinPipe()
  22. if err != nil {
  23. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_RESTARTING
  24. e.Process.Kill()
  25. return fmt.Errorf("get stdin pipe failed: %s", err.Error())
  26. }
  27. stdout, err := e.StdoutPipe()
  28. if err != nil {
  29. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_RESTARTING
  30. e.Process.Kill()
  31. return fmt.Errorf("get stdout pipe failed: %s", err.Error())
  32. }
  33. stderr, err := e.StderrPipe()
  34. if err != nil {
  35. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_RESTARTING
  36. e.Process.Kill()
  37. return fmt.Errorf("get stderr pipe failed: %s", err.Error())
  38. }
  39. if err := e.Start(); err != nil {
  40. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_RESTARTING
  41. return err
  42. }
  43. log.Info("plugin %s started", r.Config.Identity())
  44. stdio := stdio_holder.PutStdio(stdin, stdout, stderr)
  45. wg := sync.WaitGroup{}
  46. wg.Add(1)
  47. // listen to plugin stdout
  48. routine.Submit(func() {
  49. defer wg.Done()
  50. stdio.StartStdout()
  51. })
  52. err = stdio.StartStderr()
  53. if err != nil {
  54. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_RESTARTING
  55. e.Process.Kill()
  56. return err
  57. }
  58. // wait for plugin to exit
  59. err = e.Wait()
  60. if err != nil {
  61. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_RESTARTING
  62. return err
  63. }
  64. wg.Wait()
  65. // plugin has exited
  66. r.State.Status = entities.PLUGIN_RUNTIME_STATUS_PENDING
  67. return nil
  68. }