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 3.6 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
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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, target *ExecutorWriteStream) {
  20. target.stream.Stream = str
  21. e.executorSw.PutVars(target.stream)
  22. }
  23. func (e *Executor) BeginRead(target *ExecutorReadStream) (io.ReadCloser, error) {
  24. err := e.executorSw.BindVars(e.ctx, target.stream)
  25. if err != nil {
  26. return nil, fmt.Errorf("bind vars: %w", err)
  27. }
  28. return target.stream.Stream, nil
  29. }
  30. func (e *Executor) Signal(signal *ExecutorSignalVar) {
  31. e.executorSw.PutVars(signal.v)
  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.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 ExecutorStreamVar struct {
  81. // blder *PlanBuilder
  82. // v *ioswitch.StreamVar
  83. // }
  84. type ExecutorWriteStream struct {
  85. stream *ioswitch.StreamVar
  86. }
  87. // func (b *ExecutorPlanBuilder) WillWrite(str *ExecutorWriteStream) *ExecutorStreamVar {
  88. // stream := b.blder.NewStreamVar()
  89. // str.stream = stream
  90. // return &ExecutorStreamVar{blder: b.blder, v: stream}
  91. // }
  92. // func (b *ExecutorPlanBuilder) WillSignal() *ExecutorSignalVar {
  93. // s := b.blder.NewSignalVar()
  94. // return &ExecutorSignalVar{blder: b.blder, v: s}
  95. // }
  96. type ExecutorReadStream struct {
  97. stream *ioswitch.StreamVar
  98. }
  99. // func (v *ExecutorStreamVar) WillRead(str *ExecutorReadStream) {
  100. // str.stream = v.v
  101. // }
  102. /*
  103. func (s *ExecutorStreamVar) To(node cdssdk.Node) *AgentStreamVar {
  104. s.blder.ExecutorPlan.ops = append(s.blder.ExecutorPlan.ops, &ops.SendStream{Stream: s.v, Node: node})
  105. return &AgentStreamVar{
  106. owner: s.blder.AtAgent(node),
  107. v: s.v,
  108. }
  109. }
  110. type ExecutorStringVar struct {
  111. blder *PlanBuilder
  112. v *ioswitch.StringVar
  113. }
  114. func (s *ExecutorStringVar) Store(key string) {
  115. s.blder.ExecutorPlan.ops = append(s.blder.ExecutorPlan.ops, &ops.Store{
  116. Var: s.v,
  117. Key: key,
  118. Store: s.blder.StoreMap,
  119. })
  120. }
  121. type ExecutorSignalVar struct {
  122. blder *PlanBuilder
  123. v *ioswitch.SignalVar
  124. }
  125. func (s *ExecutorSignalVar) To(node cdssdk.Node) *AgentSignalVar {
  126. s.blder.ExecutorPlan.ops = append(s.blder.ExecutorPlan.ops, &ops.SendVar{Var: s.v, Node: node})
  127. return &AgentSignalVar{
  128. owner: s.blder.AtAgent(node),
  129. v: s.v,
  130. }
  131. }
  132. */

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