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.8 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package plans
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "sync"
  7. "gitlink.org.cn/cloudream/common/pkgs/future"
  8. "gitlink.org.cn/cloudream/common/utils/io2"
  9. stgglb "gitlink.org.cn/cloudream/storage/common/globals"
  10. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
  11. )
  12. type Executor struct {
  13. planID ioswitch.PlanID
  14. planBlder *PlanBuilder
  15. callback *future.SetVoidFuture
  16. ctx context.Context
  17. cancel context.CancelFunc
  18. executorSw *ioswitch.Switch
  19. }
  20. // 开始写入一个流。此函数会将输入视为一个完整的流,因此会给流包装一个Range来获取只需要的部分。
  21. func (e *Executor) BeginWrite(str io.ReadCloser, handle *ExecutorWriteStream) {
  22. handle.Var.Stream = io2.NewRange(str, handle.RangeHint.Offset, handle.RangeHint.Length)
  23. e.executorSw.PutVars(handle.Var)
  24. }
  25. // 开始写入一个流。此函数默认输入流已经是Handle的RangeHint锁描述的范围,因此不会做任何其他处理
  26. func (e *Executor) BeginWriteRanged(str io.ReadCloser, handle *ExecutorWriteStream) {
  27. handle.Var.Stream = str
  28. e.executorSw.PutVars(handle.Var)
  29. }
  30. func (e *Executor) BeginRead(handle *ExecutorReadStream) (io.ReadCloser, error) {
  31. err := e.executorSw.BindVars(e.ctx, handle.Var)
  32. if err != nil {
  33. return nil, fmt.Errorf("bind vars: %w", err)
  34. }
  35. return handle.Var.Stream, nil
  36. }
  37. func (e *Executor) Signal(signal *ExecutorSignalVar) {
  38. e.executorSw.PutVars(signal.Var)
  39. }
  40. func (e *Executor) Wait(ctx context.Context) (map[string]any, error) {
  41. err := e.callback.Wait(ctx)
  42. if err != nil {
  43. return nil, err
  44. }
  45. ret := make(map[string]any)
  46. e.planBlder.ExecutorPlan.StoreMap.Range(func(k, v any) bool {
  47. ret[k.(string)] = v
  48. return true
  49. })
  50. return ret, nil
  51. }
  52. func (e *Executor) execute() {
  53. wg := sync.WaitGroup{}
  54. for _, p := range e.planBlder.AgentPlans {
  55. wg.Add(1)
  56. go func(p *AgentPlanBuilder) {
  57. defer wg.Done()
  58. plan := ioswitch.Plan{
  59. ID: e.planID,
  60. Ops: p.Ops,
  61. }
  62. cli, err := stgglb.AgentRPCPool.Acquire(stgglb.SelectGRPCAddress(&p.Node))
  63. if err != nil {
  64. e.stopWith(fmt.Errorf("new agent rpc client of node %v: %w", p.Node.NodeID, err))
  65. return
  66. }
  67. defer stgglb.AgentRPCPool.Release(cli)
  68. err = cli.ExecuteIOPlan(e.ctx, plan)
  69. if err != nil {
  70. e.stopWith(fmt.Errorf("execute plan at %v: %w", p.Node.NodeID, err))
  71. return
  72. }
  73. }(p)
  74. }
  75. err := e.executorSw.Run(e.ctx)
  76. if err != nil {
  77. e.stopWith(fmt.Errorf("run executor switch: %w", err))
  78. return
  79. }
  80. wg.Wait()
  81. e.callback.SetVoid()
  82. }
  83. func (e *Executor) stopWith(err error) {
  84. e.callback.SetError(err)
  85. e.cancel()
  86. }
  87. type ExecutorWriteStream struct {
  88. Var *ioswitch.StreamVar
  89. RangeHint *Range
  90. }
  91. type ExecutorReadStream struct {
  92. Var *ioswitch.StreamVar
  93. }
  94. type ExecutorSignalVar struct {
  95. Var *ioswitch.SignalVar
  96. }

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