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.5 kB

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