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 2.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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/utils/io2"
  10. "golang.org/x/sync/semaphore"
  11. )
  12. func init() {
  13. exec.UseOp[*CloneStream]()
  14. exec.UseOp[*CloneVar]()
  15. }
  16. type CloneStream struct {
  17. Input *exec.StreamVar `json:"input"`
  18. Outputs []*exec.StreamVar `json:"outputs"`
  19. }
  20. func (o *CloneStream) Execute(ctx context.Context, e *exec.Executor) error {
  21. err := e.BindVars(ctx, o.Input)
  22. if err != nil {
  23. return err
  24. }
  25. defer o.Input.Stream.Close()
  26. cloned := io2.Clone(o.Input.Stream, len(o.Outputs))
  27. sem := semaphore.NewWeighted(int64(len(o.Outputs)))
  28. for i, s := range cloned {
  29. sem.Acquire(ctx, 1)
  30. o.Outputs[i].Stream = io2.AfterReadClosedOnce(s, func(closer io.ReadCloser) {
  31. sem.Release(1)
  32. })
  33. }
  34. exec.PutArrayVars(e, o.Outputs)
  35. return sem.Acquire(ctx, int64(len(o.Outputs)))
  36. }
  37. type CloneVar struct {
  38. Raw exec.Var `json:"raw"`
  39. Cloneds []exec.Var `json:"cloneds"`
  40. }
  41. func (o *CloneVar) Execute(ctx context.Context, e *exec.Executor) error {
  42. err := e.BindVars(ctx, o.Raw)
  43. if err != nil {
  44. return err
  45. }
  46. for _, v := range o.Cloneds {
  47. if err := exec.AssignVar(o.Raw, v); err != nil {
  48. return fmt.Errorf("clone var: %w", err)
  49. }
  50. }
  51. e.PutVars(o.Cloneds...)
  52. return nil
  53. }
  54. type CloneStreamType struct{}
  55. func (t *CloneStreamType) InitNode(node *dag.Node) {
  56. dag.NodeDeclareInputStream(node, 1)
  57. }
  58. func (t *CloneStreamType) GenerateOp(op *dag.Node) (exec.Op, error) {
  59. return &CloneStream{
  60. Input: op.InputStreams[0].Var,
  61. Outputs: lo.Map(op.OutputStreams, func(v *dag.StreamVar, idx int) *exec.StreamVar {
  62. return v.Var
  63. }),
  64. }, nil
  65. }
  66. func (t *CloneStreamType) NewOutput(node *dag.Node) *dag.StreamVar {
  67. return dag.NodeNewOutputStream(node, nil)
  68. }
  69. func (t *CloneStreamType) String(node *dag.Node) string {
  70. return fmt.Sprintf("CloneStream[]%v%v", formatStreamIO(node), formatValueIO(node))
  71. }
  72. type CloneVarType struct{}
  73. func (t *CloneVarType) InitNode(node *dag.Node) {
  74. dag.NodeDeclareInputValue(node, 1)
  75. }
  76. func (t *CloneVarType) GenerateOp(op *dag.Node) (exec.Op, error) {
  77. return &CloneVar{
  78. Raw: op.InputValues[0].Var,
  79. Cloneds: lo.Map(op.OutputValues, func(v *dag.ValueVar, idx int) exec.Var {
  80. return v.Var
  81. }),
  82. }, nil
  83. }
  84. func (t *CloneVarType) NewOutput(node *dag.Node) *dag.ValueVar {
  85. return dag.NodeNewOutputValue(node, node.InputValues[0].Type, nil)
  86. }
  87. func (t *CloneVarType) String(node *dag.Node) string {
  88. return fmt.Sprintf("CloneVar[]%v%v", formatStreamIO(node), formatValueIO(node))
  89. }

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