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.

executor.go 2.2 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package plans
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "sync"
  7. "gitlink.org.cn/cloudream/common/pkgs/future"
  8. stgglb "gitlink.org.cn/cloudream/storage/common/globals"
  9. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
  10. )
  11. type Executor struct {
  12. planID ioswitch.PlanID
  13. planBlder *PlanBuilder
  14. callback *future.SetVoidFuture
  15. ctx context.Context
  16. cancel context.CancelFunc
  17. executorSw *ioswitch.Switch
  18. }
  19. func (e *Executor) BeginWrite(str io.ReadCloser, handle *ExecutorWriteStream) {
  20. handle.Var.Stream = str
  21. e.executorSw.PutVars(handle.Var)
  22. }
  23. func (e *Executor) BeginRead(handle *ExecutorReadStream) (io.ReadCloser, error) {
  24. err := e.executorSw.BindVars(e.ctx, handle.Var)
  25. if err != nil {
  26. return nil, fmt.Errorf("bind vars: %w", err)
  27. }
  28. return handle.Var.Stream, nil
  29. }
  30. func (e *Executor) Signal(signal *ExecutorSignalVar) {
  31. e.executorSw.PutVars(signal.Var)
  32. }
  33. func (e *Executor) Wait(ctx context.Context) (map[string]any, error) {
  34. err := e.callback.Wait(ctx)
  35. if err != nil {
  36. return nil, err
  37. }
  38. ret := make(map[string]any)
  39. e.planBlder.ExecutorPlan.StoreMap.Range(func(k, v any) bool {
  40. ret[k.(string)] = v
  41. return true
  42. })
  43. return ret, nil
  44. }
  45. func (e *Executor) execute() {
  46. wg := sync.WaitGroup{}
  47. for _, p := range e.planBlder.AgentPlans {
  48. wg.Add(1)
  49. go func(p *AgentPlanBuilder) {
  50. defer wg.Done()
  51. plan := ioswitch.Plan{
  52. ID: e.planID,
  53. Ops: p.Ops,
  54. }
  55. cli, err := stgglb.AgentRPCPool.Acquire(stgglb.SelectGRPCAddress(&p.Node))
  56. if err != nil {
  57. e.stopWith(fmt.Errorf("new agent rpc client of node %v: %w", p.Node.NodeID, err))
  58. return
  59. }
  60. defer stgglb.AgentRPCPool.Release(cli)
  61. err = cli.ExecuteIOPlan(e.ctx, plan)
  62. if err != nil {
  63. e.stopWith(fmt.Errorf("execute plan at %v: %w", p.Node.NodeID, err))
  64. return
  65. }
  66. }(p)
  67. }
  68. err := e.executorSw.Run(e.ctx)
  69. if err != nil {
  70. e.stopWith(fmt.Errorf("run executor switch: %w", err))
  71. return
  72. }
  73. wg.Wait()
  74. e.callback.SetVoid()
  75. }
  76. func (e *Executor) stopWith(err error) {
  77. e.callback.SetError(err)
  78. e.cancel()
  79. }
  80. type ExecutorWriteStream struct {
  81. Var *ioswitch.StreamVar
  82. }
  83. type ExecutorReadStream struct {
  84. Var *ioswitch.StreamVar
  85. }
  86. type ExecutorSignalVar struct {
  87. Var *ioswitch.SignalVar
  88. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。