You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

worker.go 2.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package exec
  2. import (
  3. "context"
  4. "io"
  5. "sync"
  6. "github.com/samber/lo"
  7. "gitlink.org.cn/cloudream/common/pkgs/future"
  8. "gitlink.org.cn/cloudream/common/utils/lo2"
  9. )
  10. type finding struct {
  11. PlanID PlanID
  12. Callback *future.SetValueFuture[*Executor]
  13. }
  14. type Worker struct {
  15. lock sync.Mutex
  16. executors map[PlanID]*Executor
  17. findings []*finding
  18. }
  19. func NewWorker() Worker {
  20. return Worker{
  21. executors: make(map[PlanID]*Executor),
  22. }
  23. }
  24. func (s *Worker) Add(exe *Executor) {
  25. s.lock.Lock()
  26. defer s.lock.Unlock()
  27. s.executors[exe.Plan().ID] = exe
  28. s.findings = lo.Reject(s.findings, func(f *finding, idx int) bool {
  29. if f.PlanID != exe.Plan().ID {
  30. return false
  31. }
  32. f.Callback.SetValue(exe)
  33. return true
  34. })
  35. }
  36. func (s *Worker) Remove(sw *Executor) {
  37. s.lock.Lock()
  38. defer s.lock.Unlock()
  39. delete(s.executors, sw.Plan().ID)
  40. }
  41. func (s *Worker) FindByID(id PlanID) *Executor {
  42. s.lock.Lock()
  43. defer s.lock.Unlock()
  44. return s.executors[id]
  45. }
  46. func (s *Worker) FindByIDContexted(ctx context.Context, id PlanID) *Executor {
  47. s.lock.Lock()
  48. sw := s.executors[id]
  49. if sw != nil {
  50. s.lock.Unlock()
  51. return sw
  52. }
  53. cb := future.NewSetValue[*Executor]()
  54. f := &finding{
  55. PlanID: id,
  56. Callback: cb,
  57. }
  58. s.findings = append(s.findings, f)
  59. s.lock.Unlock()
  60. sw, _ = cb.Wait(ctx)
  61. s.lock.Lock()
  62. defer s.lock.Unlock()
  63. s.findings = lo2.Remove(s.findings, f)
  64. return sw
  65. }
  66. type WorkerInfo interface {
  67. NewClient() (WorkerClient, error)
  68. // 判断两个worker是否相同
  69. Equals(worker WorkerInfo) bool
  70. // Worker信息,比如ID、地址等
  71. String() string
  72. }
  73. type WorkerClient interface {
  74. ExecutePlan(ctx context.Context, plan Plan) error
  75. SendStream(ctx context.Context, planID PlanID, id VarID, stream io.ReadCloser) error
  76. SendVar(ctx context.Context, planID PlanID, id VarID, value VarValue) error
  77. GetStream(ctx context.Context, planID PlanID, streamID VarID, signalID VarID, signal VarValue) (io.ReadCloser, error)
  78. GetVar(ctx context.Context, planID PlanID, varID VarID, signalID VarID, signal VarValue) (VarValue, error)
  79. Close() error
  80. }