157 lines
5.0 KiB
Go
157 lines
5.0 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path"
|
|
|
|
"gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
|
|
clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
|
|
|
|
"gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
|
|
"gitlink.org.cn/cloudream/jcs-pub/client/internal/downloader/strategy"
|
|
"gitlink.org.cn/cloudream/jcs-pub/client/types"
|
|
stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals"
|
|
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2"
|
|
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/parser"
|
|
)
|
|
|
|
type UserSpaceService struct {
|
|
*Service
|
|
}
|
|
|
|
func (svc *Service) UserSpaceSvc() *UserSpaceService {
|
|
return &UserSpaceService{Service: svc}
|
|
}
|
|
|
|
func (svc *UserSpaceService) Get(userspaceID clitypes.UserSpaceID) (types.UserSpace, error) {
|
|
return svc.DB.UserSpace().GetByID(svc.DB.DefCtx(), userspaceID)
|
|
}
|
|
|
|
func (svc *UserSpaceService) GetByName(name string) (types.UserSpace, error) {
|
|
return svc.DB.UserSpace().GetByName(svc.DB.DefCtx(), name)
|
|
}
|
|
|
|
func (svc *UserSpaceService) LoadPackage(packageID clitypes.PackageID, userspaceID clitypes.UserSpaceID, rootPath string) error {
|
|
coorCli, err := stgglb.CoordinatorMQPool.Acquire()
|
|
if err != nil {
|
|
return fmt.Errorf("new coordinator client: %w", err)
|
|
}
|
|
defer stgglb.CoordinatorMQPool.Release(coorCli)
|
|
|
|
destStg := svc.UserSpaceMeta.Get(userspaceID)
|
|
if destStg == nil {
|
|
return fmt.Errorf("userspace not found: %d", userspaceID)
|
|
}
|
|
if destStg.MasterHub == nil {
|
|
return fmt.Errorf("userspace %v has no master hub", userspaceID)
|
|
}
|
|
|
|
details, err := db.DoTx11(svc.DB, svc.DB.Object().GetPackageObjectDetails, packageID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var pinned []clitypes.ObjectID
|
|
plans := exec.NewPlanBuilder()
|
|
for _, obj := range details {
|
|
strg, err := svc.StrategySelector.Select(strategy.Request{
|
|
Detail: obj,
|
|
DestHub: destStg.MasterHub.HubID,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("select download strategy: %w", err)
|
|
}
|
|
|
|
ft := ioswitch2.NewFromTo()
|
|
switch strg := strg.(type) {
|
|
case *strategy.DirectStrategy:
|
|
ft.AddFrom(ioswitch2.NewFromShardstore(strg.Detail.Object.FileHash, *strg.UserSpace.MasterHub, strg.UserSpace, ioswitch2.RawStream()))
|
|
|
|
case *strategy.ECReconstructStrategy:
|
|
for i, b := range strg.Blocks {
|
|
ft.AddFrom(ioswitch2.NewFromShardstore(b.FileHash, *strg.UserSpaces[i].MasterHub, strg.UserSpaces[i], ioswitch2.ECStream(b.Index)))
|
|
ft.ECParam = &strg.Redundancy
|
|
}
|
|
default:
|
|
return fmt.Errorf("unsupported download strategy: %T", strg)
|
|
}
|
|
|
|
ft.AddTo(ioswitch2.NewLoadToPublic(*destStg.MasterHub, *destStg, path.Join(rootPath, obj.Object.Path)))
|
|
// 顺便保存到同存储服务的分片存储中
|
|
if destStg.UserSpace.ShardStore != nil {
|
|
ft.AddTo(ioswitch2.NewToShardStore(*destStg.MasterHub, *destStg, ioswitch2.RawStream(), ""))
|
|
pinned = append(pinned, obj.Object.ObjectID)
|
|
}
|
|
|
|
err = parser.Parse(ft, plans)
|
|
if err != nil {
|
|
return fmt.Errorf("parse plan: %w", err)
|
|
}
|
|
}
|
|
|
|
// TODO2 加锁
|
|
// mutex, err := reqbuilder.NewBuilder().
|
|
// // 保护在userspace目录中下载的文件
|
|
// UserSpace().Buzy(userspaceID).
|
|
// // 保护下载文件时同时保存到IPFS的文件
|
|
// Shard().Buzy(userspaceID).
|
|
// MutexLock(svc.DistLock)
|
|
// if err != nil {
|
|
// return fmt.Errorf("acquire locks failed, err: %w", err)
|
|
// }
|
|
// defer mutex.Unlock()
|
|
|
|
// 记录访问统计
|
|
for _, obj := range details {
|
|
svc.AccessStat.AddAccessCounter(obj.Object.ObjectID, packageID, userspaceID, 1)
|
|
}
|
|
|
|
drv := plans.Execute(exec.NewExecContext())
|
|
_, err = drv.Wait(context.Background())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// 请求节点启动从UserSpace中上传文件的任务。会返回节点ID和任务ID
|
|
func (svc *UserSpaceService) UserSpaceCreatePackage(bucketID clitypes.BucketID, name string, userspaceID clitypes.UserSpaceID, path string, userspaceAffinity clitypes.UserSpaceID) (clitypes.Package, error) {
|
|
// coorCli, err := stgglb.CoordinatorMQPool.Acquire()
|
|
// if err != nil {
|
|
// return cdssdk.Package{}, fmt.Errorf("new coordinator client: %w", err)
|
|
// }
|
|
// defer stgglb.CoordinatorMQPool.Release(coorCli)
|
|
|
|
// stgResp, err := coorCli.GetUserSpaceDetails(coormq.ReqGetUserSpaceDetails([]cdssdk.UserSpaceID{userspaceID}))
|
|
// if err != nil {
|
|
// return cdssdk.Package{}, fmt.Errorf("getting userspace info: %w", err)
|
|
// }
|
|
|
|
// spaceDetail := svc.UserSpaceMeta.Get(userspaceID)
|
|
// if spaceDetail == nil {
|
|
// return cdssdk.Package{}, fmt.Errorf("userspace not found: %d", userspaceID)
|
|
// }
|
|
|
|
// if spaceDetail.UserSpace.ShardStore == nil {
|
|
// return cdssdk.Package{}, fmt.Errorf("shard userspace is not enabled")
|
|
// }
|
|
|
|
// hubCli, err := stgglb.HubMQPool.Acquire(spaceDetail.MasterHub.HubID)
|
|
// if err != nil {
|
|
// return cdssdk.Package{}, fmt.Errorf("new hub client: %w", err)
|
|
// }
|
|
// defer stgglb.HubMQPool.Release(hubCli)
|
|
|
|
// createResp, err := hubCli.UserSpaceCreatePackage(hubmq.ReqUserSpaceCreatePackage(bucketID, name, userspaceID, path, userspaceAffinity))
|
|
// if err != nil {
|
|
// return cdssdk.Package{}, err
|
|
// }
|
|
|
|
// return createResp.Package, nil
|
|
|
|
// TODO 待实现
|
|
return clitypes.Package{}, fmt.Errorf("not implemented")
|
|
}
|