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.

driver.go 2.6 kB

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