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.

create_package.go 4.1 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package task
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "time"
  6. "github.com/samber/lo"
  7. "gitlink.org.cn/cloudream/common/pkgs/logger"
  8. "gitlink.org.cn/cloudream/common/pkgs/task"
  9. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  10. stgglb "gitlink.org.cn/cloudream/storage/common/globals"
  11. "gitlink.org.cn/cloudream/storage/common/pkgs/iterator"
  12. "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator"
  13. )
  14. // CreatePackageResult 定义创建包的结果结构
  15. // 包含包的ID和上传的对象列表
  16. type CreatePackageResult struct {
  17. PackageID cdssdk.PackageID
  18. Objects []cdssdk.Object
  19. }
  20. // CreatePackage 定义创建包的任务结构
  21. // 包含用户ID、存储桶ID、包名称、上传对象的迭代器、节点亲和性以及任务结果
  22. type CreatePackage struct {
  23. userID cdssdk.UserID
  24. bucketID cdssdk.BucketID
  25. name string
  26. objIter iterator.UploadingObjectIterator
  27. stgAffinity cdssdk.StorageID
  28. Result CreatePackageResult
  29. }
  30. // NewCreatePackage 创建一个新的CreatePackage实例
  31. // userID: 用户ID
  32. // bucketID: 存储桶ID
  33. // name: 包名称
  34. // objIter: 上传对象的迭代器
  35. // stgAffinity: 节点亲和性,指定包应该创建在哪个节点上(可选)
  36. // 返回CreatePackage实例的指针
  37. func NewCreatePackage(userID cdssdk.UserID, bucketID cdssdk.BucketID, name string, objIter iterator.UploadingObjectIterator, stgAffinity cdssdk.StorageID) *CreatePackage {
  38. return &CreatePackage{
  39. userID: userID,
  40. bucketID: bucketID,
  41. name: name,
  42. objIter: objIter,
  43. stgAffinity: stgAffinity,
  44. }
  45. }
  46. // Execute 执行创建包的任务
  47. // task: 任务实例,携带任务上下文
  48. // ctx: 任务上下文,包含分布式锁和网络连接性等信息
  49. // complete: 任务完成的回调函数
  50. func (t *CreatePackage) Execute(task *task.Task[TaskContext], ctx TaskContext, complete CompleteFn) {
  51. // 获取任务日志记录器
  52. log := logger.WithType[CreatePackage]("Task")
  53. log.Debugf("begin")
  54. defer log.Debugf("end")
  55. // 从MQ池中获取协调器客户端
  56. coorCli, err := stgglb.CoordinatorMQPool.Acquire()
  57. if err != nil {
  58. err = fmt.Errorf("new coordinator client: %w", err)
  59. log.Warn(err.Error())
  60. // 完成任务并设置移除延迟
  61. complete(err, CompleteOption{
  62. RemovingDelay: time.Minute,
  63. })
  64. return
  65. }
  66. defer stgglb.CoordinatorMQPool.Release(coorCli)
  67. // 向协调器创建包
  68. createResp, err := coorCli.CreatePackage(coordinator.NewCreatePackage(t.userID, t.bucketID, t.name))
  69. if err != nil {
  70. err = fmt.Errorf("creating package: %w", err)
  71. log.Error(err.Error())
  72. // 完成任务并设置移除延迟
  73. complete(err, CompleteOption{
  74. RemovingDelay: time.Minute,
  75. })
  76. return
  77. }
  78. up, err := ctx.uploader.BeginUpdate(t.userID, createResp.Package.PackageID, t.stgAffinity, nil, nil)
  79. if err != nil {
  80. err = fmt.Errorf("begin update: %w", err)
  81. log.Error(err.Error())
  82. // 完成任务并设置移除延迟
  83. complete(err, CompleteOption{
  84. RemovingDelay: time.Minute,
  85. })
  86. return
  87. }
  88. defer up.Abort()
  89. for {
  90. obj, err := t.objIter.MoveNext()
  91. if err == iterator.ErrNoMoreItem {
  92. break
  93. }
  94. if err != nil {
  95. log.Error(err.Error())
  96. // 完成任务并设置移除延迟
  97. complete(err, CompleteOption{
  98. RemovingDelay: time.Minute,
  99. })
  100. return
  101. }
  102. path := filepath.ToSlash(obj.Path)
  103. // 上传对象
  104. err = up.Upload(path, obj.Size, obj.File)
  105. if err != nil {
  106. err = fmt.Errorf("uploading object: %w", err)
  107. log.Error(err.Error())
  108. // 完成任务并设置移除延迟
  109. complete(err, CompleteOption{
  110. RemovingDelay: time.Minute,
  111. })
  112. return
  113. }
  114. }
  115. // 结束上传
  116. uploadRet, err := up.Commit()
  117. if err != nil {
  118. err = fmt.Errorf("uploading objects: %w", err)
  119. log.Error(err.Error())
  120. // 完成任务并设置移除延迟
  121. complete(err, CompleteOption{
  122. RemovingDelay: time.Minute,
  123. })
  124. return
  125. }
  126. t.Result.PackageID = createResp.Package.PackageID
  127. t.Result.Objects = lo.Values(uploadRet.Objects)
  128. // 完成任务并设置移除延迟
  129. complete(nil, CompleteOption{
  130. RemovingDelay: time.Minute,
  131. })
  132. }

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