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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package plan
  2. import (
  3. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
  4. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
  5. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/plan/ops"
  6. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
  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. for _, out := range node.OutputStreams {
  16. to := out.Toes[0]
  17. if to.Node.Env.Equals(node.Env) {
  18. continue
  19. }
  20. switch to.Node.Env.Type {
  21. case dag.EnvDriver:
  22. // // 如果是要送到Driver,则只能由Driver主动去拉取
  23. getNode := graph.NewNode(&ops.GetStreamType{}, ioswitch.NodeProps{})
  24. getNode.Env.ToEnvDriver()
  25. // // 同时需要对此变量生成HoldUntil指令,避免Plan结束时Get指令还未到达
  26. holdNode := graph.NewNode(&ops.HoldUntilType{}, ioswitch.NodeProps{})
  27. holdNode.Env = node.Env
  28. // 将Get指令的信号送到Hold指令
  29. getNode.OutputValues[0].To(holdNode, 0)
  30. // 将Get指令的输出送到目的地
  31. getNode.OutputStreams[0].To(to.Node, to.SlotIndex)
  32. out.Toes = nil
  33. // 将源节点的输出送到Hold指令
  34. out.To(holdNode, 0)
  35. // 将Hold指令的输出送到Get指令
  36. holdNode.OutputStreams[0].To(getNode, 0)
  37. case dag.EnvWorker:
  38. // 如果是要送到Agent,则可以直接发送
  39. n := graph.NewNode(&ops.SendStreamType{}, ioswitch.NodeProps{})
  40. n.Env = node.Env
  41. n.OutputStreams[0].To(to.Node, to.SlotIndex)
  42. out.Toes = nil
  43. out.To(n, 0)
  44. }
  45. }
  46. for _, out := range node.OutputValues {
  47. to := out.Toes[0]
  48. if to.Node.Env.Equals(node.Env) {
  49. continue
  50. }
  51. switch to.Node.Env.Type {
  52. case dag.EnvDriver:
  53. // // 如果是要送到Driver,则只能由Driver主动去拉取
  54. getNode := graph.NewNode(&ops.GetVaType{}, ioswitch.NodeProps{})
  55. getNode.Env.ToEnvDriver()
  56. // // 同时需要对此变量生成HoldUntil指令,避免Plan结束时Get指令还未到达
  57. holdNode := graph.NewNode(&ops.HoldUntilType{}, ioswitch.NodeProps{})
  58. holdNode.Env = node.Env
  59. // 将Get指令的信号送到Hold指令
  60. getNode.OutputValues[0].To(holdNode, 0)
  61. // 将Get指令的输出送到目的地
  62. getNode.OutputValues[1].To(to.Node, to.SlotIndex)
  63. out.Toes = nil
  64. // 将源节点的输出送到Hold指令
  65. out.To(holdNode, 0)
  66. // 将Hold指令的输出送到Get指令
  67. holdNode.OutputValues[0].To(getNode, 0)
  68. case dag.EnvWorker:
  69. // 如果是要送到Agent,则可以直接发送
  70. n := graph.NewNode(&ops.SendVarType{}, ioswitch.NodeProps{})
  71. n.Env = node.Env
  72. n.OutputValues[0].To(to.Node, to.SlotIndex)
  73. out.Toes = nil
  74. out.To(n, 0)
  75. }
  76. }
  77. return true
  78. })
  79. }
  80. // 生成Plan
  81. func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error {
  82. var retErr error
  83. graph.Walk(func(node *dag.Node) bool {
  84. for _, out := range node.OutputStreams {
  85. if out.Var != nil {
  86. continue
  87. }
  88. out.Var = blder.NewStreamVar()
  89. }
  90. for _, in := range node.InputStreams {
  91. if in.Var != nil {
  92. continue
  93. }
  94. in.Var = blder.NewStreamVar()
  95. }
  96. for _, out := range node.OutputValues {
  97. if out.Var != nil {
  98. continue
  99. }
  100. switch out.Type {
  101. case dag.StringValueVar:
  102. out.Var = blder.NewStringVar()
  103. case dag.SignalValueVar:
  104. out.Var = blder.NewSignalVar()
  105. }
  106. }
  107. for _, in := range node.InputValues {
  108. if in.Var != nil {
  109. continue
  110. }
  111. switch in.Type {
  112. case dag.StringValueVar:
  113. in.Var = blder.NewStringVar()
  114. case dag.SignalValueVar:
  115. in.Var = blder.NewSignalVar()
  116. }
  117. }
  118. op, err := node.Type.GenerateOp(node)
  119. if err != nil {
  120. retErr = err
  121. return false
  122. }
  123. switch node.Env.Type {
  124. case dag.EnvDriver:
  125. blder.AtDriver().AddOp(op)
  126. case dag.EnvWorker:
  127. blder.AtWorker(node.Env.Worker).AddOp(op)
  128. }
  129. return true
  130. })
  131. return retErr
  132. }