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.

update.go 3.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package uploader
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "path"
  7. "sync"
  8. "time"
  9. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
  10. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  11. stgglb "gitlink.org.cn/cloudream/storage/common/globals"
  12. stgmod "gitlink.org.cn/cloudream/storage/common/models"
  13. "gitlink.org.cn/cloudream/storage/common/pkgs/distlock"
  14. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2"
  15. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/ops2"
  16. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/parser"
  17. coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator"
  18. )
  19. type UpdateUploader struct {
  20. uploader *Uploader
  21. pkgID cdssdk.PackageID
  22. targetStg stgmod.StorageDetail
  23. distMutex *distlock.Mutex
  24. loadToStgs []stgmod.StorageDetail
  25. loadToPath []string
  26. successes []coormq.AddObjectEntry
  27. lock sync.Mutex
  28. commited bool
  29. }
  30. type UploadStorageInfo struct {
  31. Storage stgmod.StorageDetail
  32. Delay time.Duration
  33. IsSameLocation bool
  34. }
  35. type UpdateResult struct {
  36. // 上传成功的文件列表,Key为Path
  37. Objects map[string]cdssdk.Object
  38. }
  39. func (w *UpdateUploader) Upload(pat string, size int64, stream io.Reader) error {
  40. uploadTime := time.Now()
  41. ft := ioswitch2.NewFromTo()
  42. fromExec, hd := ioswitch2.NewFromDriver(ioswitch2.RawStream())
  43. ft.AddFrom(fromExec).
  44. AddTo(ioswitch2.NewToShardStore(*w.targetStg.MasterHub, w.targetStg, ioswitch2.RawStream(), "fileHash"))
  45. for i, stg := range w.loadToStgs {
  46. ft.AddTo(ioswitch2.NewLoadToShared(*stg.MasterHub, stg, path.Join(w.loadToPath[i], pat)))
  47. }
  48. plans := exec.NewPlanBuilder()
  49. err := parser.Parse(ft, plans)
  50. if err != nil {
  51. return fmt.Errorf("parsing plan: %w", err)
  52. }
  53. exeCtx := exec.NewExecContext()
  54. exec.SetValueByType(exeCtx, w.uploader.stgAgts)
  55. exec := plans.Execute(exeCtx)
  56. exec.BeginWrite(io.NopCloser(stream), hd)
  57. ret, err := exec.Wait(context.TODO())
  58. if err != nil {
  59. return fmt.Errorf("executing plan: %w", err)
  60. }
  61. w.lock.Lock()
  62. defer w.lock.Unlock()
  63. // 记录上传结果
  64. w.successes = append(w.successes, coormq.AddObjectEntry{
  65. Path: pat,
  66. Size: size,
  67. FileHash: ret["fileHash"].(*ops2.FileHashValue).Hash,
  68. UploadTime: uploadTime,
  69. StorageIDs: []cdssdk.StorageID{w.targetStg.Storage.StorageID},
  70. })
  71. return nil
  72. }
  73. func (w *UpdateUploader) Commit() (UpdateResult, error) {
  74. w.lock.Lock()
  75. defer w.lock.Unlock()
  76. if w.commited {
  77. return UpdateResult{}, fmt.Errorf("package already commited")
  78. }
  79. w.commited = true
  80. defer w.distMutex.Unlock()
  81. coorCli, err := stgglb.CoordinatorMQPool.Acquire()
  82. if err != nil {
  83. return UpdateResult{}, fmt.Errorf("new coordinator client: %w", err)
  84. }
  85. defer stgglb.CoordinatorMQPool.Release(coorCli)
  86. updateResp, err := coorCli.UpdatePackage(coormq.NewUpdatePackage(w.pkgID, w.successes, nil))
  87. if err != nil {
  88. return UpdateResult{}, fmt.Errorf("updating package: %w", err)
  89. }
  90. ret := UpdateResult{
  91. Objects: make(map[string]cdssdk.Object),
  92. }
  93. for _, entry := range updateResp.Added {
  94. ret.Objects[entry.Path] = entry
  95. }
  96. return ret, nil
  97. }
  98. func (w *UpdateUploader) Abort() {
  99. w.lock.Lock()
  100. defer w.lock.Unlock()
  101. if w.commited {
  102. return
  103. }
  104. w.commited = true
  105. w.distMutex.Unlock()
  106. }

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