|
- package cmd
-
- import (
- "fmt"
-
- "github.com/samber/lo"
-
- stgsdk "gitlink.org.cn/cloudream/common/sdks/storage"
-
- stgglb "gitlink.org.cn/cloudream/storage/common/globals"
- "gitlink.org.cn/cloudream/storage/common/pkgs/db/model"
- "gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder"
- "gitlink.org.cn/cloudream/storage/common/pkgs/iterator"
- coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator"
- )
-
- type UpdateECPackage struct {
- userID int64
- packageID int64
- objectIter iterator.UploadingObjectIterator
- }
-
- type UpdateECPackageResult struct {
- ObjectResults []ECObjectUploadResult
- }
-
- func NewUpdateECPackage(userID int64, packageID int64, objIter iterator.UploadingObjectIterator) *UpdateECPackage {
- return &UpdateECPackage{
- userID: userID,
- packageID: packageID,
- objectIter: objIter,
- }
- }
-
- func (t *UpdateECPackage) Execute(ctx *UpdatePackageContext) (*UpdateECPackageResult, error) {
- defer t.objectIter.Close()
-
- coorCli, err := stgglb.CoordinatorMQPool.Acquire()
- if err != nil {
- return nil, fmt.Errorf("new coordinator client: %w", err)
- }
-
- mutex, err := reqbuilder.NewBuilder().
- Metadata().
- // 用于查询可用的上传节点
- Node().ReadAny().
- // 用于创建包信息
- Package().WriteOne(t.packageID).
- // 用于创建包中的文件的信息
- Object().CreateAny().
- // 用于设置EC配置
- ObjectBlock().CreateAny().
- // 用于创建Cache记录
- Cache().CreateAny().
- MutexLock(ctx.Distlock)
- if err != nil {
- return nil, fmt.Errorf("acquire locks failed, err: %w", err)
- }
- defer mutex.Unlock()
-
- getPkgResp, err := coorCli.GetPackage(coormq.NewGetPackage(t.userID, t.packageID))
- if err != nil {
- return nil, fmt.Errorf("getting package: %w", err)
- }
-
- getUserNodesResp, err := coorCli.GetUserNodes(coormq.NewGetUserNodes(t.userID))
- if err != nil {
- return nil, fmt.Errorf("getting user nodes: %w", err)
- }
-
- findCliLocResp, err := coorCli.FindClientLocation(coormq.NewFindClientLocation(stgglb.Local.ExternalIP))
- if err != nil {
- return nil, fmt.Errorf("finding client location: %w", err)
- }
-
- nodeInfos := lo.Map(getUserNodesResp.Nodes, func(node model.Node, index int) UploadNodeInfo {
- return UploadNodeInfo{
- Node: node,
- IsSameLocation: node.LocationID == findCliLocResp.Location.LocationID,
- }
- })
-
- var ecInfo stgsdk.ECRedundancyInfo
- if ecInfo, err = getPkgResp.Package.Redundancy.ToECInfo(); err != nil {
- return nil, fmt.Errorf("get ec redundancy info: %w", err)
- }
-
- getECResp, err := coorCli.GetECConfig(coormq.NewGetECConfig(ecInfo.ECName))
- if err != nil {
- return nil, fmt.Errorf("getting ec: %w", err)
- }
-
- // 给上传节点的IPFS加锁
- ipfsReqBlder := reqbuilder.NewBuilder()
- // 如果本地的IPFS也是存储系统的一个节点,那么从本地上传时,需要加锁
- if stgglb.Local.NodeID != nil {
- ipfsReqBlder.IPFS().CreateAnyRep(*stgglb.Local.NodeID)
- }
- for _, node := range nodeInfos {
- if stgglb.Local.NodeID != nil && node.Node.NodeID == *stgglb.Local.NodeID {
- continue
- }
-
- ipfsReqBlder.IPFS().CreateAnyRep(node.Node.NodeID)
- }
- // 防止上传的副本被清除
- ipfsMutex, err := ipfsReqBlder.MutexLock(ctx.Distlock)
- if err != nil {
- return nil, fmt.Errorf("acquire locks failed, err: %w", err)
- }
- defer ipfsMutex.Unlock()
-
- rets, err := uploadAndUpdateECPackage(t.packageID, t.objectIter, nodeInfos, ecInfo, getECResp.Config)
- if err != nil {
- return nil, err
- }
-
- return &UpdateECPackageResult{
- ObjectResults: rets,
- }, nil
- }
|