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.

ops.go 3.0 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package ops
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "gitlink.org.cn/cloudream/common/pkgs/future"
  7. "gitlink.org.cn/cloudream/common/pkgs/logger"
  8. "gitlink.org.cn/cloudream/common/pkgs/types"
  9. myio "gitlink.org.cn/cloudream/common/utils/io"
  10. "gitlink.org.cn/cloudream/common/utils/serder"
  11. stgglb "gitlink.org.cn/cloudream/storage/common/globals"
  12. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
  13. )
  14. var OpUnion = serder.UseTypeUnionExternallyTagged(types.Ref(types.NewTypeUnion[ioswitch.Op](
  15. (*IPFSRead)(nil),
  16. (*IPFSWrite)(nil),
  17. (*Join)(nil),
  18. )))
  19. type IPFSRead struct {
  20. Output ioswitch.StreamID `json:"output"`
  21. FileHash string `json:"fileHash"`
  22. }
  23. func (o *IPFSRead) Execute(sw *ioswitch.Switch, planID ioswitch.PlanID) error {
  24. logger.
  25. WithField("FileHash", o.FileHash).
  26. WithField("Output", o.Output).
  27. Debugf("ipfs read op")
  28. defer logger.Debugf("ipfs read op finished")
  29. ipfsCli, err := stgglb.IPFSPool.Acquire()
  30. if err != nil {
  31. return fmt.Errorf("new ipfs client: %w", err)
  32. }
  33. defer stgglb.IPFSPool.Release(ipfsCli)
  34. file, err := ipfsCli.OpenRead(o.FileHash)
  35. if err != nil {
  36. return fmt.Errorf("reading ipfs: %w", err)
  37. }
  38. fut := future.NewSetVoid()
  39. file = myio.AfterReadClosedOnce(file, func(closer io.ReadCloser) {
  40. fut.SetVoid()
  41. })
  42. sw.StreamReady(planID, ioswitch.NewStream(o.Output, file))
  43. // TODO context
  44. fut.Wait(context.TODO())
  45. return nil
  46. }
  47. type IPFSWrite struct {
  48. Input ioswitch.StreamID `json:"input"`
  49. ResultKey string `json:"resultKey"`
  50. }
  51. func (o *IPFSWrite) Execute(sw *ioswitch.Switch, planID ioswitch.PlanID) error {
  52. logger.
  53. WithField("ResultKey", o.ResultKey).
  54. WithField("Input", o.Input).
  55. Debugf("ipfs write op")
  56. ipfsCli, err := stgglb.IPFSPool.Acquire()
  57. if err != nil {
  58. return fmt.Errorf("new ipfs client: %w", err)
  59. }
  60. defer stgglb.IPFSPool.Release(ipfsCli)
  61. strs, err := sw.WaitStreams(planID, o.Input)
  62. if err != nil {
  63. return err
  64. }
  65. defer strs[0].Stream.Close()
  66. fileHash, err := ipfsCli.CreateFile(strs[0].Stream)
  67. if err != nil {
  68. return fmt.Errorf("creating ipfs file: %w", err)
  69. }
  70. if o.ResultKey != "" {
  71. sw.AddResultValue(planID, ioswitch.ResultKV{
  72. Key: o.ResultKey,
  73. Value: fileHash,
  74. })
  75. }
  76. return nil
  77. }
  78. type Join struct {
  79. InputIDs []ioswitch.StreamID `json:"inputIDs"`
  80. OutputID ioswitch.StreamID `json:"outputID"`
  81. Length int64 `json:"length"`
  82. }
  83. func (o *Join) Execute(sw *ioswitch.Switch, planID ioswitch.PlanID) error {
  84. strs, err := sw.WaitStreams(planID, o.InputIDs...)
  85. if err != nil {
  86. return err
  87. }
  88. var strReaders []io.Reader
  89. for _, s := range strs {
  90. strReaders = append(strReaders, s.Stream)
  91. }
  92. defer func() {
  93. for _, str := range strs {
  94. str.Stream.Close()
  95. }
  96. }()
  97. fut := future.NewSetVoid()
  98. sw.StreamReady(planID,
  99. ioswitch.NewStream(o.OutputID,
  100. myio.AfterReadClosedOnce(myio.Length(myio.Join(strReaders), o.Length), func(closer io.ReadCloser) {
  101. fut.SetVoid()
  102. }),
  103. ),
  104. )
  105. fut.Wait(context.TODO())
  106. return nil
  107. }

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