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.

generate.go 4.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package plan
  2. import (
  3. "fmt"
  4. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
  5. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
  6. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/plan/ops"
  7. )
  8. func Generate(graph *dag.Graph, planBld *exec.PlanBuilder) error {
  9. generateSend(graph)
  10. return buildPlan(graph, planBld)
  11. }
  12. // 生成Send指令
  13. func generateSend(graph *dag.Graph) {
  14. graph.Walk(func(node *dag.Node) bool {
  15. switch node.Type.(type) {
  16. case *ops.SendStreamType:
  17. return true
  18. case *ops.SendVarType:
  19. return true
  20. case *ops.GetStreamType:
  21. return true
  22. case *ops.GetVaType:
  23. return true
  24. case *ops.HoldUntilType:
  25. return true
  26. }
  27. for _, out := range node.OutputStreams {
  28. to := out.Toes[0]
  29. if to.Node.Env.Equals(node.Env) {
  30. continue
  31. }
  32. switch to.Node.Env.Type {
  33. case dag.EnvDriver:
  34. // // 如果是要送到Driver,则只能由Driver主动去拉取
  35. getNode, getType := dag.NewNode(graph, &ops.GetStreamType{
  36. FromWorker: node.Env.Worker,
  37. }, nil)
  38. getNode.Env.ToEnvDriver()
  39. // // 同时需要对此变量生成HoldUntil指令,避免Plan结束时Get指令还未到达
  40. holdNode, holdType := dag.NewNode(graph, &ops.HoldUntilType{}, nil)
  41. holdNode.Env = node.Env
  42. // 将Get指令的信号送到Hold指令
  43. holdType.Signal(holdNode, getType.SignalVar(getNode))
  44. out.Toes = nil
  45. // 将源节点的输出送到Hold指令,将Hold指令的输出送到Get指令
  46. getType.Get(getNode, holdType.HoldStream(holdNode, out)).
  47. // 将Get指令的输出送到目的地
  48. To(to.Node, to.SlotIndex)
  49. case dag.EnvWorker:
  50. // 如果是要送到Agent,则可以直接发送
  51. n, t := dag.NewNode(graph, &ops.SendStreamType{
  52. ToWorker: to.Node.Env.Worker,
  53. }, nil)
  54. n.Env = node.Env
  55. out.Toes = nil
  56. t.Send(n, out).To(to.Node, to.SlotIndex)
  57. }
  58. }
  59. for _, out := range node.OutputValues {
  60. to := out.Toes[0]
  61. if to.Node.Env.Equals(node.Env) {
  62. continue
  63. }
  64. switch to.Node.Env.Type {
  65. case dag.EnvDriver:
  66. // // 如果是要送到Driver,则只能由Driver主动去拉取
  67. getNode, getType := dag.NewNode(graph, &ops.GetVaType{
  68. FromWorker: node.Env.Worker,
  69. }, nil)
  70. getNode.Env.ToEnvDriver()
  71. // // 同时需要对此变量生成HoldUntil指令,避免Plan结束时Get指令还未到达
  72. holdNode, holdType := dag.NewNode(graph, &ops.HoldUntilType{}, nil)
  73. holdNode.Env = node.Env
  74. // 将Get指令的信号送到Hold指令
  75. holdType.Signal(holdNode, getType.SignalVar(getNode))
  76. out.Toes = nil
  77. // 将源节点的输出送到Hold指令,将Hold指令的输出送到Get指令
  78. getType.Get(getNode, holdType.HoldVar(holdNode, out)).
  79. // 将Get指令的输出送到目的地
  80. To(to.Node, to.SlotIndex)
  81. case dag.EnvWorker:
  82. // 如果是要送到Agent,则可以直接发送
  83. n, t := dag.NewNode(graph, &ops.SendVarType{
  84. ToWorker: to.Node.Env.Worker,
  85. }, nil)
  86. n.Env = node.Env
  87. out.Toes = nil
  88. t.Send(n, out).To(to.Node, to.SlotIndex)
  89. }
  90. }
  91. return true
  92. })
  93. }
  94. // 生成Plan
  95. func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error {
  96. var retErr error
  97. graph.Walk(func(node *dag.Node) bool {
  98. for _, out := range node.OutputStreams {
  99. if out.Var != nil {
  100. continue
  101. }
  102. out.Var = blder.NewStreamVar()
  103. }
  104. for _, in := range node.InputStreams {
  105. if in.Var != nil {
  106. continue
  107. }
  108. in.Var = blder.NewStreamVar()
  109. }
  110. for _, out := range node.OutputValues {
  111. if out.Var != nil {
  112. continue
  113. }
  114. switch out.Type {
  115. case dag.StringValueVar:
  116. out.Var = blder.NewStringVar()
  117. case dag.SignalValueVar:
  118. out.Var = blder.NewSignalVar()
  119. default:
  120. retErr = fmt.Errorf("unsupported value var type: %v", out.Type)
  121. return false
  122. }
  123. }
  124. for _, in := range node.InputValues {
  125. if in.Var != nil {
  126. continue
  127. }
  128. switch in.Type {
  129. case dag.StringValueVar:
  130. in.Var = blder.NewStringVar()
  131. case dag.SignalValueVar:
  132. in.Var = blder.NewSignalVar()
  133. default:
  134. retErr = fmt.Errorf("unsupported value var type: %v", in.Type)
  135. return false
  136. }
  137. }
  138. op, err := node.Type.GenerateOp(node)
  139. if err != nil {
  140. retErr = err
  141. return false
  142. }
  143. // TODO 当前ToDriver,FromDriver不会生成Op,所以这里需要判断一下
  144. if op == nil {
  145. return true
  146. }
  147. switch node.Env.Type {
  148. case dag.EnvDriver:
  149. blder.AtDriver().AddOp(op)
  150. case dag.EnvWorker:
  151. blder.AtWorker(node.Env.Worker).AddOp(op)
  152. }
  153. return true
  154. })
  155. return retErr
  156. }