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

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

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