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_package.go 2.4 kB

2 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package cmd
  2. import (
  3. "fmt"
  4. "github.com/samber/lo"
  5. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  6. stgglb "gitlink.org.cn/cloudream/storage/common/globals"
  7. "gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder"
  8. "gitlink.org.cn/cloudream/storage/common/pkgs/iterator"
  9. coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator"
  10. )
  11. type UpdatePackage struct {
  12. userID cdssdk.UserID
  13. packageID cdssdk.PackageID
  14. objectIter iterator.UploadingObjectIterator
  15. }
  16. type UpdatePackageResult struct {
  17. ObjectResults []ObjectUploadResult
  18. }
  19. type UpdateNodeInfo struct {
  20. UploadNodeInfo
  21. HasOldObject bool
  22. }
  23. func NewUpdatePackage(userID cdssdk.UserID, packageID cdssdk.PackageID, objIter iterator.UploadingObjectIterator) *UpdatePackage {
  24. return &UpdatePackage{
  25. userID: userID,
  26. packageID: packageID,
  27. objectIter: objIter,
  28. }
  29. }
  30. func (t *UpdatePackage) Execute(ctx *UpdatePackageContext) (*UpdatePackageResult, error) {
  31. defer t.objectIter.Close()
  32. coorCli, err := stgglb.CoordinatorMQPool.Acquire()
  33. if err != nil {
  34. return nil, fmt.Errorf("new coordinator client: %w", err)
  35. }
  36. getUserNodesResp, err := coorCli.GetUserNodes(coormq.NewGetUserNodes(t.userID))
  37. if err != nil {
  38. return nil, fmt.Errorf("getting user nodes: %w", err)
  39. }
  40. userNodes := lo.Map(getUserNodesResp.Nodes, func(node cdssdk.Node, index int) UploadNodeInfo {
  41. return UploadNodeInfo{
  42. Node: node,
  43. IsSameLocation: node.LocationID == stgglb.Local.LocationID,
  44. }
  45. })
  46. // 给上传节点的IPFS加锁
  47. ipfsReqBlder := reqbuilder.NewBuilder()
  48. // 如果本地的IPFS也是存储系统的一个节点,那么从本地上传时,需要加锁
  49. if stgglb.Local.NodeID != nil {
  50. ipfsReqBlder.IPFS().Buzy(*stgglb.Local.NodeID)
  51. }
  52. for _, node := range userNodes {
  53. if stgglb.Local.NodeID != nil && node.Node.NodeID == *stgglb.Local.NodeID {
  54. continue
  55. }
  56. ipfsReqBlder.IPFS().Buzy(node.Node.NodeID)
  57. }
  58. // TODO 加Object的Create锁,最好一次性能加多个
  59. // 防止上传的副本被清除
  60. ipfsMutex, err := ipfsReqBlder.MutexLock(ctx.Distlock)
  61. if err != nil {
  62. return nil, fmt.Errorf("acquire locks failed, err: %w", err)
  63. }
  64. defer ipfsMutex.Unlock()
  65. rets, err := uploadAndUpdatePackage(t.packageID, t.objectIter, userNodes, nil)
  66. if err != nil {
  67. return nil, err
  68. }
  69. return &UpdatePackageResult{
  70. ObjectResults: rets,
  71. }, nil
  72. }

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