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.

clone.go 3.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package ops2
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "github.com/samber/lo"
  7. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
  8. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
  9. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/utils"
  10. "gitlink.org.cn/cloudream/common/utils/io2"
  11. "golang.org/x/sync/semaphore"
  12. )
  13. func init() {
  14. exec.UseOp[*CloneStream]()
  15. exec.UseOp[*CloneVar]()
  16. }
  17. type CloneStream struct {
  18. Raw *exec.StreamVar `json:"raw"`
  19. Cloneds []*exec.StreamVar `json:"cloneds"`
  20. }
  21. func (o *CloneStream) Execute(ctx context.Context, e *exec.Executor) error {
  22. err := e.BindVars(ctx, o.Raw)
  23. if err != nil {
  24. return err
  25. }
  26. defer o.Raw.Stream.Close()
  27. cloned := io2.Clone(o.Raw.Stream, len(o.Cloneds))
  28. sem := semaphore.NewWeighted(int64(len(o.Cloneds)))
  29. for i, s := range cloned {
  30. sem.Acquire(ctx, 1)
  31. o.Cloneds[i].Stream = io2.AfterReadClosedOnce(s, func(closer io.ReadCloser) {
  32. sem.Release(1)
  33. })
  34. }
  35. exec.PutArrayVars(e, o.Cloneds)
  36. return sem.Acquire(ctx, int64(len(o.Cloneds)))
  37. }
  38. func (o *CloneStream) String() string {
  39. return fmt.Sprintf("CloneStream %v -> (%v)", o.Raw.ID, utils.FormatVarIDs(o.Cloneds))
  40. }
  41. type CloneVar struct {
  42. Raw exec.Var `json:"raw"`
  43. Cloneds []exec.Var `json:"cloneds"`
  44. }
  45. func (o *CloneVar) Execute(ctx context.Context, e *exec.Executor) error {
  46. err := e.BindVars(ctx, o.Raw)
  47. if err != nil {
  48. return err
  49. }
  50. for _, v := range o.Cloneds {
  51. if err := exec.AssignVar(o.Raw, v); err != nil {
  52. return fmt.Errorf("clone var: %w", err)
  53. }
  54. }
  55. e.PutVars(o.Cloneds...)
  56. return nil
  57. }
  58. func (o *CloneVar) String() string {
  59. return fmt.Sprintf("CloneStream %v -> (%v)", o.Raw.GetID(), utils.FormatVarIDs(o.Cloneds))
  60. }
  61. type CloneStreamType struct {
  62. dag.NodeBase
  63. }
  64. func (b *GraphNodeBuilder) NewCloneStream() *CloneStreamType {
  65. node := &CloneStreamType{}
  66. b.AddNode(node)
  67. return node
  68. }
  69. func (t *CloneStreamType) SetInput(raw *dag.StreamVar) {
  70. t.InputStreams().EnsureSize(1)
  71. raw.Connect(t, 0)
  72. }
  73. func (t *CloneStreamType) NewOutput() *dag.StreamVar {
  74. output := t.Graph().NewStreamVar()
  75. t.OutputStreams().SetupNew(t, output)
  76. return output
  77. }
  78. func (t *CloneStreamType) GenerateOp() (exec.Op, error) {
  79. return &CloneStream{
  80. Raw: t.InputStreams().Get(0).Var,
  81. Cloneds: lo.Map(t.OutputStreams().RawArray(), func(v *dag.StreamVar, idx int) *exec.StreamVar {
  82. return v.Var
  83. }),
  84. }, nil
  85. }
  86. // func (t *CloneStreamType) String() string {
  87. // return fmt.Sprintf("CloneStream[]%v%v", formatStreamIO(node), formatValueIO(node))
  88. // }
  89. type CloneVarType struct {
  90. dag.NodeBase
  91. }
  92. func (b *GraphNodeBuilder) NewCloneValue() *CloneVarType {
  93. node := &CloneVarType{}
  94. b.AddNode(node)
  95. return node
  96. }
  97. func (t *CloneVarType) SetInput(raw *dag.ValueVar) {
  98. t.InputValues().EnsureSize(1)
  99. raw.Connect(t, 0)
  100. }
  101. func (t *CloneVarType) NewOutput() *dag.ValueVar {
  102. output := t.Graph().NewValueVar(t.InputValues().Get(0).Type)
  103. t.OutputValues().SetupNew(t, output)
  104. return output
  105. }
  106. func (t *CloneVarType) GenerateOp() (exec.Op, error) {
  107. return &CloneVar{
  108. Raw: t.InputValues().Get(0).Var,
  109. Cloneds: lo.Map(t.OutputValues().RawArray(), func(v *dag.ValueVar, idx int) exec.Var {
  110. return v.Var
  111. }),
  112. }, nil
  113. }
  114. // func (t *CloneVarType) String() string {
  115. // return fmt.Sprintf("CloneVar[]%v%v", formatStreamIO(node), formatValueIO(node))
  116. // }

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