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

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

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