From 3ff3d9cf384961386c78bda32245e7642c73de1e Mon Sep 17 00:00:00 2001 From: Sydonian <794346190@qq.com> Date: Tue, 20 May 2025 16:20:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=96=E6=B6=88MasterHub=E7=9A=84=E6=A6=82?= =?UTF-8?q?=E5=BF=B5=EF=BC=8C=E6=94=B9=E4=B8=BA=E9=80=9A=E8=BF=87Location?= =?UTF-8?q?=E5=8C=B9=E9=85=8DHub=EF=BC=9B=E8=B0=83=E6=95=B4=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/internal/cmdline/test.go | 8 +- client/internal/downloader/iterator.go | 6 +- client/internal/downloader/lrc.go | 2 +- .../internal/downloader/lrc_strip_iterator.go | 2 +- .../internal/downloader/strategy/selector.go | 20 +-- client/internal/downloader/strip_iterator.go | 2 +- client/internal/metacache/storagemeta.go | 17 +- client/internal/services/object.go | 2 +- client/internal/services/user_space.go | 42 ++--- client/internal/ticktock/change_redundancy.go | 3 - client/internal/ticktock/check_shardstore.go | 11 +- .../internal/ticktock/redundancy_recover.go | 77 +++------ client/internal/ticktock/redundancy_shrink.go | 12 +- client/internal/ticktock/shardstore_gc.go | 4 +- client/internal/uploader/create_load.go | 6 +- client/internal/uploader/update.go | 6 +- client/internal/uploader/uploader.go | 23 +-- client/internal/uploader/user_space_upload.go | 35 ++--- client/types/types.go | 15 +- common/pkgs/ioswitch2/fromto.go | 34 ++-- common/pkgs/ioswitch2/ops2/bypass.go | 56 +++---- common/pkgs/ioswitch2/ops2/public_store.go | 148 ++++++++++-------- common/pkgs/ioswitch2/ops2/s2s.go | 2 +- common/pkgs/ioswitch2/ops2/shard_store.go | 12 +- common/pkgs/ioswitch2/parser/gen/generator.go | 20 +-- common/pkgs/ioswitch2/parser/opt/ec.go | 8 +- common/pkgs/ioswitch2/parser/opt/s2s.go | 24 +-- .../ioswitch2/plans/complete_multipart.go | 6 +- common/pkgs/ioswitchlrc/fromto.go | 12 +- common/pkgs/ioswitchlrc/parser/passes.go | 6 +- common/pkgs/rpc/coordinator/coordinator.pb.go | 22 +-- common/pkgs/rpc/coordinator/coordinator.proto | 2 +- .../rpc/coordinator/coordinator_grpc.pb.go | 26 +-- common/pkgs/rpc/coordinator/storage.go | 31 ++-- common/pkgs/rpc/hub/hub.pb.go | 8 +- common/pkgs/rpc/hub/hub.proto | 4 +- common/pkgs/rpc/hub/hub_grpc.pb.go | 52 +++--- common/pkgs/rpc/hub/user_space.go | 34 ++-- common/pkgs/storage/efile/efile.go | 7 +- common/pkgs/storage/factory/factory.go | 2 +- common/pkgs/storage/factory/reg/reg.go | 2 +- common/pkgs/storage/local/local.go | 10 +- common/pkgs/storage/local/public_store.go | 42 +++-- common/pkgs/storage/local/s2s.go | 4 +- common/pkgs/storage/local/shard_store.go | 17 +- common/pkgs/storage/mashup/mashup.go | 30 ++-- common/pkgs/storage/obs/obs.go | 30 ++-- common/pkgs/storage/obs/obs_test.go | 19 +-- common/pkgs/storage/obs/s2s.go | 32 ++-- common/pkgs/storage/obs/shard_store.go | 10 +- common/pkgs/storage/pool/pool.go | 4 +- common/pkgs/storage/s3/public_store.go | 79 ++++++++-- common/pkgs/storage/s3/s3.go | 26 +-- common/pkgs/storage/s3/shard_store.go | 22 +-- common/pkgs/storage/types/bypass.go | 4 +- common/pkgs/storage/types/empty_builder.go | 12 +- common/pkgs/storage/types/public_store.go | 8 +- common/pkgs/storage/types/types.go | 4 +- common/pkgs/storage/utils/utils.go | 5 +- coordinator/internal/cmd/migrate.go | 3 +- coordinator/internal/db/hub_location.go | 25 +++ coordinator/internal/db/location.go | 36 ----- coordinator/internal/db/storage.go | 43 ----- coordinator/internal/rpc/storage.go | 86 ++++++---- coordinator/types/location.go | 6 + coordinator/types/storage.go | 148 +++++++++++++++--- coordinator/types/storage_credential.go | 28 +--- coordinator/types/types.go | 19 +-- hub/internal/rpc/user_space.go | 12 +- 69 files changed, 820 insertions(+), 755 deletions(-) create mode 100644 coordinator/internal/db/hub_location.go delete mode 100644 coordinator/internal/db/location.go delete mode 100644 coordinator/internal/db/storage.go create mode 100644 coordinator/types/location.go diff --git a/client/internal/cmdline/test.go b/client/internal/cmdline/test.go index 1f73d4f..f2af776 100644 --- a/client/internal/cmdline/test.go +++ b/client/internal/cmdline/test.go @@ -46,8 +46,8 @@ func doTest(svc *services.Service) { space1 := svc.UserSpaceMeta.Get(3) space2 := svc.UserSpaceMeta.Get(4) - // ft.AddFrom(ioswitch2.NewFromPublicStore(*space1.MasterHub, *space1, "space3/blocks/1A/Full1AE5436AF72D8EF93923486E0E167315CEF0C91898064DADFAC22216FFBC5E3D")) - // ft.AddTo(ioswitch2.NewToPublicStore(*space2.MasterHub, *space2, "block")) + // ft.AddFrom(ioswitch2.NewFromBaseStore(*space1.MasterHub, *space1, "space3/blocks/1A/Full1AE5436AF72D8EF93923486E0E167315CEF0C91898064DADFAC22216FFBC5E3D")) + // ft.AddTo(ioswitch2.NewToBaseStore(*space2.MasterHub, *space2, "block")) // plans := exec.NewPlanBuilder() // parser.Parse(ft, plans) // fmt.Println(plans) @@ -56,8 +56,8 @@ func doTest(svc *services.Service) { // fmt.Println(err) ft = ioswitch2.NewFromTo() - ft.AddFrom(ioswitch2.NewFromShardstore("Full1AE5436AF72D8EF93923486E0E167315CEF0C91898064DADFAC22216FFBC5E3D", *space1.MasterHub, *space1, ioswitch2.RawStream())) - ft.AddTo(ioswitch2.NewToPublicStore(*space2.MasterHub, *space2, "test3.txt")) + ft.AddFrom(ioswitch2.NewFromShardstore("Full1AE5436AF72D8EF93923486E0E167315CEF0C91898064DADFAC22216FFBC5E3D", *space1, ioswitch2.RawStream())) + ft.AddTo(ioswitch2.NewToBaseStore(*space2, "test3.txt")) plans := exec.NewPlanBuilder() parser.Parse(ft, plans) fmt.Println(plans) diff --git a/client/internal/downloader/iterator.go b/client/internal/downloader/iterator.go index a4f30d3..bec0b2d 100644 --- a/client/internal/downloader/iterator.go +++ b/client/internal/downloader/iterator.go @@ -109,7 +109,7 @@ func (i *DownloadObjectIterator) Close() { } func (i *DownloadObjectIterator) downloadDirect(req downloadReqeust2, strg strategy.DirectStrategy) (io.ReadCloser, error) { - logger.Debugf("downloading object %v from storage %v", req.Raw.ObjectID, strg.UserSpace.Storage.String()) + logger.Debugf("downloading object %v from storage %v", req.Raw.ObjectID, strg.UserSpace.UserSpace.Storage.String()) var strHandle *exec.DriverReadStream ft := ioswitch2.NewFromTo() @@ -123,7 +123,7 @@ func (i *DownloadObjectIterator) downloadDirect(req downloadReqeust2, strg strat toExec.Range.Length = &len } - ft.AddFrom(ioswitch2.NewFromShardstore(req.Detail.Object.FileHash, *strg.UserSpace.MasterHub, strg.UserSpace, ioswitch2.RawStream())).AddTo(toExec) + ft.AddFrom(ioswitch2.NewFromShardstore(req.Detail.Object.FileHash, strg.UserSpace, ioswitch2.RawStream())).AddTo(toExec) strHandle = handle plans := exec.NewPlanBuilder() @@ -146,7 +146,7 @@ func (i *DownloadObjectIterator) downloadECReconstruct(req downloadReqeust2, str logStrs = append(logStrs, ", ") } - logStrs = append(logStrs, fmt.Sprintf("%v@%v", b.Index, strg.UserSpaces[i].Storage.String())) + logStrs = append(logStrs, fmt.Sprintf("%v@%v", b.Index, strg.UserSpaces[i].UserSpace.Storage.String())) } logger.Debug(logStrs...) diff --git a/client/internal/downloader/lrc.go b/client/internal/downloader/lrc.go index a59c33c..0d64e1d 100644 --- a/client/internal/downloader/lrc.go +++ b/client/internal/downloader/lrc.go @@ -18,7 +18,7 @@ func (iter *DownloadObjectIterator) downloadLRCReconstruct(req downloadReqeust2, logStrs = append(logStrs, ", ") } - logStrs = append(logStrs, fmt.Sprintf("%v@%v", b.Index, strg.Spaces[i].Storage.String())) + logStrs = append(logStrs, fmt.Sprintf("%v@%v", b.Index, strg.Spaces[i].UserSpace.Storage.String())) } logger.Debug(logStrs...) diff --git a/client/internal/downloader/lrc_strip_iterator.go b/client/internal/downloader/lrc_strip_iterator.go index 9b94e67..bff86d2 100644 --- a/client/internal/downloader/lrc_strip_iterator.go +++ b/client/internal/downloader/lrc_strip_iterator.go @@ -99,7 +99,7 @@ func (s *LRCStripIterator) downloading() { var froms []ioswitchlrc.From for _, b := range s.blocks { space := b.Space - froms = append(froms, ioswitchlrc.NewFromStorage(b.Block.FileHash, *space.MasterHub, space, b.Block.Index)) + froms = append(froms, ioswitchlrc.NewFromStorage(b.Block.FileHash, space, b.Block.Index)) } toExec, hd := ioswitchlrc.NewToDriverWithRange(-1, math2.Range{ diff --git a/client/internal/downloader/strategy/selector.go b/client/internal/downloader/strategy/selector.go index 0837809..5580265 100644 --- a/client/internal/downloader/strategy/selector.go +++ b/client/internal/downloader/strategy/selector.go @@ -62,7 +62,7 @@ func (s *LRCReconstructStrategy) GetDetail() types.ObjectDetail { type Selector struct { cfg Config - storageMeta *metacache.UserSpaceMeta + spaceMeta *metacache.UserSpaceMeta hubMeta *metacache.HubMeta connectivity *metacache.Connectivity } @@ -70,7 +70,7 @@ type Selector struct { func NewSelector(cfg Config, storageMeta *metacache.UserSpaceMeta, hubMeta *metacache.HubMeta, connectivity *metacache.Connectivity) *Selector { return &Selector{ cfg: cfg, - storageMeta: storageMeta, + spaceMeta: storageMeta, hubMeta: hubMeta, connectivity: connectivity, } @@ -232,8 +232,8 @@ func (s *Selector) sortDownloadStorages(req request2) []*downloadSpaceInfo { for _, id := range req.Detail.PinnedAt { storage, ok := downloadSpaceMap[id] if !ok { - mod := s.storageMeta.Get(id) - if mod == nil || mod.MasterHub == nil { + mod := s.spaceMeta.Get(id) + if mod == nil { continue } @@ -251,8 +251,8 @@ func (s *Selector) sortDownloadStorages(req request2) []*downloadSpaceInfo { for _, b := range req.Detail.Blocks { space, ok := downloadSpaceMap[b.UserSpaceID] if !ok { - mod := s.storageMeta.Get(b.UserSpaceID) - if mod == nil || mod.MasterHub == nil { + mod := s.spaceMeta.Get(b.UserSpaceID) + if mod == nil { continue } @@ -273,15 +273,15 @@ func (s *Selector) sortDownloadStorages(req request2) []*downloadSpaceInfo { func (s *Selector) getStorageDistance(req request2, src types.UserSpaceDetail) float64 { if req.DestHub != nil { - if src.MasterHub.HubID == req.DestHub.HubID { + if src.RecommendHub.HubID == req.DestHub.HubID { return consts.StorageDistanceSameStorage } - if src.MasterHub.LocationID == req.DestHub.LocationID { + if src.RecommendHub.LocationID == req.DestHub.LocationID { return consts.StorageDistanceSameLocation } - latency := s.connectivity.Get(src.MasterHub.HubID, req.DestHub.HubID) + latency := s.connectivity.Get(src.RecommendHub.HubID, req.DestHub.HubID) if latency == nil || *latency > time.Duration(float64(time.Millisecond)*s.cfg.HighLatencyHubMs) { return consts.HubDistanceHighLatencyHub } @@ -290,7 +290,7 @@ func (s *Selector) getStorageDistance(req request2, src types.UserSpaceDetail) f } if req.DestLocation != 0 { - if src.MasterHub.LocationID == req.DestLocation { + if src.RecommendHub.LocationID == req.DestLocation { return consts.StorageDistanceSameLocation } } diff --git a/client/internal/downloader/strip_iterator.go b/client/internal/downloader/strip_iterator.go index d44ca74..58e938a 100644 --- a/client/internal/downloader/strip_iterator.go +++ b/client/internal/downloader/strip_iterator.go @@ -202,7 +202,7 @@ func (s *StripIterator) readStrip(stripIndex int64, buf []byte) (int, error) { ft.ECParam = &s.red for _, b := range s.blocks { space := b.Space - ft.AddFrom(ioswitch2.NewFromShardstore(b.Block.FileHash, *space.MasterHub, space, ioswitch2.ECStream(b.Block.Index))) + ft.AddFrom(ioswitch2.NewFromShardstore(b.Block.FileHash, space, ioswitch2.ECStream(b.Block.Index))) } toExec, hd := ioswitch2.NewToDriverWithRange(ioswitch2.RawStream(), math2.Range{ diff --git a/client/internal/metacache/storagemeta.go b/client/internal/metacache/storagemeta.go index 3e5f287..c34e4ac 100644 --- a/client/internal/metacache/storagemeta.go +++ b/client/internal/metacache/storagemeta.go @@ -65,24 +65,25 @@ func (s *UserSpaceMeta) load(keys []types.UserSpaceID) ([]types.UserSpaceDetail, coorCli := stgglb.CoordinatorRPCPool.Get() defer coorCli.Release() - stgIDs := make([]cortypes.StorageID, len(spaces)) + stgs := make([]cortypes.StorageType, len(spaces)) for i := range spaces { - stgIDs[i] = spaces[i].StorageID + stgs[i] = spaces[i].Storage } - getStgs, cerr := coorCli.GetStorageDetails(context.Background(), corrpc.ReqGetStorageDetails(stgIDs)) + selectHubs, cerr := coorCli.SelectStorageHub(context.Background(), &corrpc.SelectStorageHub{ + Storages: stgs, + }) if cerr != nil { logger.Warnf("get storage details: %v", cerr) return vs, oks } for i := range spaces { - if getStgs.Storage[i] != nil { + if selectHubs.Hubs[i] != nil { vs[i] = types.UserSpaceDetail{ - UserID: stgglb.Local.UserID, - UserSpace: spaces[i], - Storage: getStgs.Storage[i].Storage, - MasterHub: getStgs.Storage[i].MasterHub, + UserID: stgglb.Local.UserID, + UserSpace: spaces[i], + RecommendHub: *selectHubs.Hubs[i], } oks[i] = true diff --git a/client/internal/services/object.go b/client/internal/services/object.go index 41e4c40..8789b53 100644 --- a/client/internal/services/object.go +++ b/client/internal/services/object.go @@ -714,7 +714,7 @@ func (svc *ObjectService) CompleteMultipartUpload(objectID types.ObjectID, index return types.Object{}, err } - shardInfo := ret["shard"].(*ops2.ShardInfoValue) + shardInfo := ret["shard"].(*ops2.FileInfoValue) err = db.DoTx10(svc.DB, svc.DB.Object().BatchUpdateRedundancy, []db.UpdatingObjectRedundancy{ { diff --git a/client/internal/services/user_space.go b/client/internal/services/user_space.go index 64ac883..d377d50 100644 --- a/client/internal/services/user_space.go +++ b/client/internal/services/user_space.go @@ -47,9 +47,6 @@ func (svc *UserSpaceService) DownloadPackage(packageID clitypes.PackageID, users 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 { @@ -61,7 +58,7 @@ func (svc *UserSpaceService) DownloadPackage(packageID clitypes.PackageID, users for _, obj := range details { strg, err := svc.StrategySelector.Select(strategy.Request{ Detail: obj, - DestHub: destStg.MasterHub.HubID, + DestHub: destStg.RecommendHub.HubID, }) if err != nil { return fmt.Errorf("select download strategy: %w", err) @@ -70,21 +67,21 @@ func (svc *UserSpaceService) DownloadPackage(packageID clitypes.PackageID, users 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())) + ft.AddFrom(ioswitch2.NewFromShardstore(strg.Detail.Object.FileHash, 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.AddFrom(ioswitch2.NewFromShardstore(b.FileHash, strg.UserSpaces[i], ioswitch2.ECStream(b.Index))) ft.ECParam = &strg.Redundancy } default: return fmt.Errorf("unsupported download strategy: %T", strg) } - ft.AddTo(ioswitch2.NewToPublicStore(*destStg.MasterHub, *destStg, path.Join(rootPath, obj.Object.Path))) + ft.AddTo(ioswitch2.NewToBaseStore(*destStg, path.Join(rootPath, obj.Object.Path))) // 顺便保存到同存储服务的分片存储中 if destStg.UserSpace.ShardStore != nil { - ft.AddTo(ioswitch2.NewToShardStore(*destStg.MasterHub, *destStg, ioswitch2.RawStream(), "")) + ft.AddTo(ioswitch2.NewToShardStore(*destStg, ioswitch2.RawStream(), "")) pinned = append(pinned, obj.Object.ObjectID) } @@ -121,29 +118,24 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa if srcSpace == nil { return clitypes.SpaceToSpaceResult{}, fmt.Errorf("source userspace not found: %d", srcSpaceID) } - if srcSpace.MasterHub == nil { - return clitypes.SpaceToSpaceResult{}, fmt.Errorf("source userspace %v has no master hub", srcSpaceID) - } - srcAddr, ok := srcSpace.MasterHub.Address.(*cortypes.GRPCAddressInfo) + srcAddr, ok := srcSpace.RecommendHub.Address.(*cortypes.GRPCAddressInfo) if !ok { return clitypes.SpaceToSpaceResult{}, fmt.Errorf("source userspace %v has no grpc address", srcSpaceID) } - srcSpaceCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(srcSpace.MasterHub, srcAddr)) + srcSpaceCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(&srcSpace.RecommendHub, srcAddr)) defer srcSpaceCli.Release() dstSpace := svc.UserSpaceMeta.Get(dstSpaceID) if dstSpace == nil { return clitypes.SpaceToSpaceResult{}, fmt.Errorf("destination userspace not found: %d", dstSpaceID) } - if dstSpace.MasterHub == nil { - return clitypes.SpaceToSpaceResult{}, fmt.Errorf("destination userspace %v has no master hub", dstSpaceID) - } - dstAddr, ok := dstSpace.MasterHub.Address.(*cortypes.GRPCAddressInfo) + + dstAddr, ok := dstSpace.RecommendHub.Address.(*cortypes.GRPCAddressInfo) if !ok { return clitypes.SpaceToSpaceResult{}, fmt.Errorf("destination userspace %v has no grpc address", srcSpaceID) } - dstSpaceCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(dstSpace.MasterHub, dstAddr)) + dstSpaceCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(&dstSpace.RecommendHub, dstAddr)) defer dstSpaceCli.Release() srcPath = strings.Trim(srcPath, cdssdk.ObjectPathSeparator) @@ -157,7 +149,7 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa return clitypes.SpaceToSpaceResult{}, fmt.Errorf("destination path is empty") } - listAllResp, cerr := srcSpaceCli.PublicStoreListAll(context.Background(), &hubrpc.PublicStoreListAll{ + listAllResp, cerr := srcSpaceCli.BaseStoreListAll(context.Background(), &hubrpc.BaseStoreListAll{ UserSpace: *srcSpace, Path: srcPath, }) @@ -168,7 +160,7 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa srcPathComps := clitypes.SplitObjectPath(srcPath) srcDirCompLen := len(srcPathComps) - 1 - entryTree := trie.NewTrie[*types.PublicStoreEntry]() + entryTree := trie.NewTrie[*types.BaseStoreEntry]() for _, e := range listAllResp.Entries { pa, ok := strings.CutSuffix(e.Path, clitypes.ObjectPathSeparator) comps := clitypes.SplitObjectPath(pa) @@ -179,7 +171,7 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa e2.IsDir = e2.IsDir || ok } - entryTree.Iterate(func(path []string, node *trie.Node[*types.PublicStoreEntry], isWordNode bool) trie.VisitCtrl { + entryTree.Iterate(func(path []string, node *trie.Node[*types.BaseStoreEntry], isWordNode bool) trie.VisitCtrl { if node.Value == nil { return trie.VisitContinue } @@ -198,7 +190,7 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa var filePathes []string var dirPathes []string - entryTree.Iterate(func(path []string, node *trie.Node[*types.PublicStoreEntry], isWordNode bool) trie.VisitCtrl { + entryTree.Iterate(func(path []string, node *trie.Node[*types.BaseStoreEntry], isWordNode bool) trie.VisitCtrl { if node.Value == nil { return trie.VisitContinue } @@ -219,8 +211,8 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa newPath := strings.Replace(f, srcPath, dstPath, 1) ft := ioswitch2.NewFromTo() - ft.AddFrom(ioswitch2.NewFromPublicStore(*srcSpace.MasterHub, *srcSpace, f)) - ft.AddTo(ioswitch2.NewToPublicStore(*dstSpace.MasterHub, *dstSpace, newPath)) + ft.AddFrom(ioswitch2.NewFromBaseStore(*srcSpace, f)) + ft.AddTo(ioswitch2.NewToBaseStore(*dstSpace, newPath)) plans := exec.NewPlanBuilder() err := parser.Parse(ft, plans) @@ -245,7 +237,7 @@ func (svc *UserSpaceService) SpaceToSpace(srcSpaceID clitypes.UserSpaceID, srcPa newDirPathes = append(newDirPathes, strings.Replace(dirPathes[i], srcPath, dstPath, 1)) } - mkdirResp, err := dstSpaceCli.PublicStoreMkdirs(context.Background(), &hubrpc.PublicStoreMkdirs{ + mkdirResp, err := dstSpaceCli.BaseStoreMkdirs(context.Background(), &hubrpc.BaseStoreMkdirs{ UserSpace: *dstSpace, Pathes: newDirPathes, }) diff --git a/client/internal/ticktock/change_redundancy.go b/client/internal/ticktock/change_redundancy.go index 9aaf739..6797f58 100644 --- a/client/internal/ticktock/change_redundancy.go +++ b/client/internal/ticktock/change_redundancy.go @@ -48,9 +48,6 @@ func (j *ChangeRedundancy) Execute(t *TickTock) { if space == nil { continue } - if space.MasterHub == nil { - continue - } ctx.allUserSpaces[space.UserSpace.UserSpaceID] = &userSpaceUsageInfo{ UserSpace: space, diff --git a/client/internal/ticktock/check_shardstore.go b/client/internal/ticktock/check_shardstore.go index a7a1d59..b56cc0c 100644 --- a/client/internal/ticktock/check_shardstore.go +++ b/client/internal/ticktock/check_shardstore.go @@ -56,18 +56,11 @@ func (j *CheckShardStore) Execute(t *TickTock) { } func (j *CheckShardStore) checkOne(t *TickTock, space *clitypes.UserSpaceDetail) error { - log := logger.WithType[CheckShardStore]("TickTock") - - if space.MasterHub == nil { - log.Infof("user space %v has no master hub", space.UserSpace) - return nil - } - - addr, ok := space.MasterHub.Address.(*cortypes.GRPCAddressInfo) + addr, ok := space.RecommendHub.Address.(*cortypes.GRPCAddressInfo) if !ok { return fmt.Errorf("master of user space %v has no grpc address", space.UserSpace) } - agtCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(space.MasterHub, addr)) + agtCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(&space.RecommendHub, addr)) defer agtCli.Release() ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute)) diff --git a/client/internal/ticktock/redundancy_recover.go b/client/internal/ticktock/redundancy_recover.go index 4dbb79c..fc3d856 100644 --- a/client/internal/ticktock/redundancy_recover.go +++ b/client/internal/ticktock/redundancy_recover.go @@ -307,12 +307,12 @@ func (t *ChangeRedundancy) chooseSoManyUserSpaces(count int, stgs []*userSpaceUs continue } - if chosenLocations[stg.UserSpace.MasterHub.LocationID] { + if chosenLocations[stg.UserSpace.RecommendHub.LocationID] { continue } chosen = append(chosen, stg) - chosenLocations[stg.UserSpace.MasterHub.LocationID] = true + chosenLocations[stg.UserSpace.RecommendHub.LocationID] = true extendStgs[i] = nil } } @@ -329,17 +329,14 @@ func (t *ChangeRedundancy) noneToRep(ctx *changeRedundancyContext, obj clitypes. if !ok { return nil, nil, fmt.Errorf("userspace %v not found", obj.Blocks[0].UserSpaceID) } - if srcStg.UserSpace.MasterHub == nil { - return nil, nil, fmt.Errorf("userspace %v has no master hub", obj.Blocks[0].UserSpaceID) - } // 如果选择的备份节点都是同一个,那么就只要上传一次 uploadStgs = lo.UniqBy(uploadStgs, func(item *userSpaceUsageInfo) clitypes.UserSpaceID { return item.UserSpace.UserSpace.UserSpaceID }) ft := ioswitch2.NewFromTo() - ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace.MasterHub, *srcStg.UserSpace, ioswitch2.RawStream())) + ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace, ioswitch2.RawStream())) for i, stg := range uploadStgs { - ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace.MasterHub, *stg.UserSpace, ioswitch2.RawStream(), fmt.Sprintf("%d", i))) + ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace, ioswitch2.RawStream(), fmt.Sprintf("%d", i))) } plans := exec.NewPlanBuilder() @@ -359,7 +356,7 @@ func (t *ChangeRedundancy) noneToRep(ctx *changeRedundancyContext, obj clitypes. var blocks []clitypes.ObjectBlock var blockChgs []datamap.BlockChange for i, stg := range uploadStgs { - r := ret[fmt.Sprintf("%d", i)].(*ops2.ShardInfoValue) + r := ret[fmt.Sprintf("%d", i)].(*ops2.FileInfoValue) blocks = append(blocks, clitypes.ObjectBlock{ ObjectID: obj.Object.ObjectID, Index: 0, @@ -403,15 +400,12 @@ func (t *ChangeRedundancy) noneToEC(ctx *changeRedundancyContext, obj clitypes.O if !ok { return nil, nil, fmt.Errorf("userspace %v not found", obj.Blocks[0].UserSpaceID) } - if srcStg.UserSpace.MasterHub == nil { - return nil, nil, fmt.Errorf("userspace %v has no master hub", obj.Blocks[0].UserSpaceID) - } ft := ioswitch2.NewFromTo() ft.ECParam = red - ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace.MasterHub, *srcStg.UserSpace, ioswitch2.RawStream())) + ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace, ioswitch2.RawStream())) for i := 0; i < red.N; i++ { - ft.AddTo(ioswitch2.NewToShardStore(*uploadStgs[i].UserSpace.MasterHub, *uploadStgs[i].UserSpace, ioswitch2.ECStream(i), fmt.Sprintf("%d", i))) + ft.AddTo(ioswitch2.NewToShardStore(*uploadStgs[i].UserSpace, ioswitch2.ECStream(i), fmt.Sprintf("%d", i))) } plans := exec.NewPlanBuilder() err := parser.Parse(ft, plans) @@ -430,7 +424,7 @@ func (t *ChangeRedundancy) noneToEC(ctx *changeRedundancyContext, obj clitypes.O var evtTargetBlocks []datamap.Block var evtBlockTrans []datamap.DataTransfer for i := 0; i < red.N; i++ { - r := ioRet[fmt.Sprintf("%d", i)].(*ops2.ShardInfoValue) + r := ioRet[fmt.Sprintf("%d", i)].(*ops2.FileInfoValue) blocks = append(blocks, clitypes.ObjectBlock{ ObjectID: obj.Object.ObjectID, Index: i, @@ -488,17 +482,14 @@ func (t *ChangeRedundancy) noneToLRC(ctx *changeRedundancyContext, obj clitypes. if !ok { return nil, nil, fmt.Errorf("userspace %v not found", obj.Blocks[0].UserSpaceID) } - if srcStg.UserSpace.MasterHub == nil { - return nil, nil, fmt.Errorf("userspace %v has no master hub", obj.Blocks[0].UserSpaceID) - } var toes []ioswitchlrc.To for i := 0; i < red.N; i++ { - toes = append(toes, ioswitchlrc.NewToStorage(*uploadStgs[i].UserSpace.MasterHub, *uploadStgs[i].UserSpace, i, fmt.Sprintf("%d", i))) + toes = append(toes, ioswitchlrc.NewToStorage(*uploadStgs[i].UserSpace, i, fmt.Sprintf("%d", i))) } plans := exec.NewPlanBuilder() - err := lrcparser.Encode(ioswitchlrc.NewFromStorage(obj.Object.FileHash, *srcStg.UserSpace.MasterHub, *srcStg.UserSpace, -1), toes, plans) + err := lrcparser.Encode(ioswitchlrc.NewFromStorage(obj.Object.FileHash, *srcStg.UserSpace, -1), toes, plans) if err != nil { return nil, nil, fmt.Errorf("parsing plan: %w", err) } @@ -514,7 +505,7 @@ func (t *ChangeRedundancy) noneToLRC(ctx *changeRedundancyContext, obj clitypes. var evtTargetBlocks []datamap.Block var evtBlockTrans []datamap.DataTransfer for i := 0; i < red.N; i++ { - r := ioRet[fmt.Sprintf("%d", i)].(*ops2.ShardInfoValue) + r := ioRet[fmt.Sprintf("%d", i)].(*ops2.FileInfoValue) blocks = append(blocks, clitypes.ObjectBlock{ ObjectID: obj.Object.ObjectID, Index: i, @@ -573,18 +564,15 @@ func (t *ChangeRedundancy) noneToSeg(ctx *changeRedundancyContext, obj clitypes. if !ok { return nil, nil, fmt.Errorf("userspace %v not found", obj.Blocks[0].UserSpaceID) } - if srcStg.UserSpace.MasterHub == nil { - return nil, nil, fmt.Errorf("userspace %v has no master hub", obj.Blocks[0].UserSpaceID) - } // 如果选择的备份节点都是同一个,那么就只要上传一次 uploadStgs = lo.UniqBy(uploadStgs, func(item *userSpaceUsageInfo) clitypes.UserSpaceID { return item.UserSpace.UserSpace.UserSpaceID }) ft := ioswitch2.NewFromTo() ft.SegmentParam = red - ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace.MasterHub, *srcStg.UserSpace, ioswitch2.RawStream())) + ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace, ioswitch2.RawStream())) for i, stg := range uploadStgs { - ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace.MasterHub, *stg.UserSpace, ioswitch2.SegmentStream(i), fmt.Sprintf("%d", i))) + ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace, ioswitch2.SegmentStream(i), fmt.Sprintf("%d", i))) } plans := exec.NewPlanBuilder() @@ -605,7 +593,7 @@ func (t *ChangeRedundancy) noneToSeg(ctx *changeRedundancyContext, obj clitypes. var evtTargetBlocks []datamap.Block var evtBlockTrans []datamap.DataTransfer for i, stg := range uploadStgs { - r := ret[fmt.Sprintf("%d", i)].(*ops2.ShardInfoValue) + r := ret[fmt.Sprintf("%d", i)].(*ops2.FileInfoValue) blocks = append(blocks, clitypes.ObjectBlock{ ObjectID: obj.Object.ObjectID, Index: i, @@ -664,17 +652,14 @@ func (t *ChangeRedundancy) repToRep(ctx *changeRedundancyContext, obj clitypes.O if !ok { return nil, nil, fmt.Errorf("userspace %v not found", obj.Blocks[0].UserSpaceID) } - if srcStg.UserSpace.MasterHub == nil { - return nil, nil, fmt.Errorf("userspace %v has no master hub", obj.Blocks[0].UserSpaceID) - } // 如果选择的备份节点都是同一个,那么就只要上传一次 uploadStgs = lo.UniqBy(uploadStgs, func(item *userSpaceUsageInfo) clitypes.UserSpaceID { return item.UserSpace.UserSpace.UserSpaceID }) ft := ioswitch2.NewFromTo() - ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace.MasterHub, *srcStg.UserSpace, ioswitch2.RawStream())) + ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *srcStg.UserSpace, ioswitch2.RawStream())) for i, stg := range uploadStgs { - ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace.MasterHub, *stg.UserSpace, ioswitch2.RawStream(), fmt.Sprintf("%d", i))) + ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace, ioswitch2.RawStream(), fmt.Sprintf("%d", i))) } plans := exec.NewPlanBuilder() @@ -694,7 +679,7 @@ func (t *ChangeRedundancy) repToRep(ctx *changeRedundancyContext, obj clitypes.O var blocks []clitypes.ObjectBlock var blockChgs []datamap.BlockChange for i, stg := range uploadStgs { - r := ret[fmt.Sprintf("%d", i)].(*ops2.ShardInfoValue) + r := ret[fmt.Sprintf("%d", i)].(*ops2.FileInfoValue) blocks = append(blocks, clitypes.ObjectBlock{ ObjectID: obj.Object.ObjectID, Index: 0, @@ -746,9 +731,6 @@ func (t *ChangeRedundancy) ecToRep(ctx *changeRedundancyContext, obj clitypes.Ob if !ok { continue } - if stg.UserSpace.MasterHub == nil { - continue - } chosenBlocks = append(chosenBlocks, block) chosenBlockIndexes = append(chosenBlockIndexes, block.Index) @@ -772,11 +754,11 @@ func (t *ChangeRedundancy) ecToRep(ctx *changeRedundancyContext, obj clitypes.Ob ft.ECParam = srcRed for i, block := range chosenBlocks { - ft.AddFrom(ioswitch2.NewFromShardstore(block.FileHash, *chosenBlockStg[i].MasterHub, chosenBlockStg[i], ioswitch2.ECStream(block.Index))) + ft.AddFrom(ioswitch2.NewFromShardstore(block.FileHash, chosenBlockStg[i], ioswitch2.ECStream(block.Index))) } for i := range uploadStgs { - ft.AddTo(ioswitch2.NewToShardStoreWithRange(*uploadStgs[i].UserSpace.MasterHub, *uploadStgs[i].UserSpace, ioswitch2.RawStream(), fmt.Sprintf("%d", i), math2.NewRange(0, obj.Object.Size))) + ft.AddTo(ioswitch2.NewToShardStoreWithRange(*uploadStgs[i].UserSpace, ioswitch2.RawStream(), fmt.Sprintf("%d", i), math2.NewRange(0, obj.Object.Size))) } err := parser.Parse(ft, planBlder) @@ -795,7 +777,7 @@ func (t *ChangeRedundancy) ecToRep(ctx *changeRedundancyContext, obj clitypes.Ob var blocks []clitypes.ObjectBlock for i := range uploadStgs { - r := ioRet[fmt.Sprintf("%d", i)].(*ops2.ShardInfoValue) + r := ioRet[fmt.Sprintf("%d", i)].(*ops2.FileInfoValue) blocks = append(blocks, clitypes.ObjectBlock{ ObjectID: obj.Object.ObjectID, Index: 0, @@ -874,10 +856,6 @@ func (t *ChangeRedundancy) ecToEC(ctx *changeRedundancyContext, obj clitypes.Obj if !ok { continue } - if stg.UserSpace.MasterHub == nil { - continue - } - chosenBlocks = append(chosenBlocks, block) chosenBlockStg = append(chosenBlockStg, *stg.UserSpace) } @@ -901,7 +879,7 @@ func (t *ChangeRedundancy) ecToEC(ctx *changeRedundancyContext, obj clitypes.Obj ft.ECParam = srcRed for i, block := range chosenBlocks { - ft.AddFrom(ioswitch2.NewFromShardstore(block.FileHash, *chosenBlockStg[i].MasterHub, chosenBlockStg[i], ioswitch2.ECStream(block.Index))) + ft.AddFrom(ioswitch2.NewFromShardstore(block.FileHash, chosenBlockStg[i], ioswitch2.ECStream(block.Index))) evtSrcBlocks = append(evtSrcBlocks, datamap.Block{ BlockType: datamap.BlockTypeEC, @@ -933,7 +911,7 @@ func (t *ChangeRedundancy) ecToEC(ctx *changeRedundancyContext, obj clitypes.Obj // 否则就要重建出这个节点需要的块 // 输出只需要自己要保存的那一块 - ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace.MasterHub, *stg.UserSpace, ioswitch2.ECStream(i), fmt.Sprintf("%d", i))) + ft.AddTo(ioswitch2.NewToShardStore(*stg.UserSpace, ioswitch2.ECStream(i), fmt.Sprintf("%d", i))) evtTargetBlocks = append(evtTargetBlocks, datamap.Block{ BlockType: datamap.BlockTypeEC, @@ -967,7 +945,7 @@ func (t *ChangeRedundancy) ecToEC(ctx *changeRedundancyContext, obj clitypes.Obj return nil, nil, fmt.Errorf("parsing result key %s as index: %w", k, err) } - r := v.(*ops2.ShardInfoValue) + r := v.(*ops2.FileInfoValue) newBlocks[idx].FileHash = r.Hash newBlocks[idx].Size = r.Size } @@ -1132,9 +1110,6 @@ func (t *ChangeRedundancy) reconstructLRC(ctx *changeRedundancyContext, obj clit if !ok { continue } - if stg.UserSpace.MasterHub == nil { - continue - } chosenBlocks = append(chosenBlocks, block) chosenBlockStg = append(chosenBlockStg, *stg.UserSpace) @@ -1178,11 +1153,11 @@ func (t *ChangeRedundancy) reconstructLRC(ctx *changeRedundancyContext, obj clit // 否则就要重建出这个节点需要的块 for i2, block := range chosenBlocks { - froms = append(froms, ioswitchlrc.NewFromStorage(block.FileHash, *chosenBlockStg[i2].MasterHub, chosenBlockStg[i2], block.Index)) + froms = append(froms, ioswitchlrc.NewFromStorage(block.FileHash, chosenBlockStg[i2], block.Index)) } // 输出只需要自己要保存的那一块 - toes = append(toes, ioswitchlrc.NewToStorage(*userspace.UserSpace.MasterHub, *userspace.UserSpace, i, fmt.Sprintf("%d", i))) + toes = append(toes, ioswitchlrc.NewToStorage(*userspace.UserSpace, i, fmt.Sprintf("%d", i))) newBlocks = append(newBlocks, newBlock) } @@ -1212,7 +1187,7 @@ func (t *ChangeRedundancy) reconstructLRC(ctx *changeRedundancyContext, obj clit return nil, nil, fmt.Errorf("parsing result key %s as index: %w", k, err) } - r := v.(*ops2.ShardInfoValue) + r := v.(*ops2.FileInfoValue) newBlocks[idx].FileHash = r.Hash newBlocks[idx].Size = r.Size } diff --git a/client/internal/ticktock/redundancy_shrink.go b/client/internal/ticktock/redundancy_shrink.go index ce49d07..a6fe812 100644 --- a/client/internal/ticktock/redundancy_shrink.go +++ b/client/internal/ticktock/redundancy_shrink.go @@ -557,7 +557,7 @@ func (t *ChangeRedundancy) sortNodeByReaderDistance(state *annealingState) { UserSpaceID: n, Distance: consts.StorageDistanceSameStorage, }) - } else if state.ctx.allUserSpaces[r].UserSpace.MasterHub.LocationID == state.ctx.allUserSpaces[n].UserSpace.MasterHub.LocationID { + } else if state.ctx.allUserSpaces[r].UserSpace.RecommendHub.LocationID == state.ctx.allUserSpaces[n].UserSpace.RecommendHub.LocationID { // 同地区时距离视为1 nodeDists = append(nodeDists, stgDist{ UserSpaceID: n, @@ -680,7 +680,7 @@ func (t *ChangeRedundancy) makePlansForRepObject(ctx *changeRedundancyContext, s ft := ioswitch2.NewFromTo() fromStg := ctx.allUserSpaces[obj.Blocks[0].UserSpaceID].UserSpace - ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *fromStg.MasterHub, *fromStg, ioswitch2.RawStream())) + ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *fromStg, ioswitch2.RawStream())) for i, f := range solu.rmBlocks { hasCache := lo.ContainsBy(obj.Blocks, func(b clitypes.ObjectBlock) bool { return b.UserSpaceID == solu.blockList[i].UserSpaceID }) || @@ -691,7 +691,7 @@ func (t *ChangeRedundancy) makePlansForRepObject(ctx *changeRedundancyContext, s // 如果对象在退火后要保留副本的节点没有副本,则需要在这个节点创建副本 if !hasCache { toStg := ctx.allUserSpaces[solu.blockList[i].UserSpaceID].UserSpace - ft.AddTo(ioswitch2.NewToShardStore(*toStg.MasterHub, *toStg, ioswitch2.RawStream(), fmt.Sprintf("%d.0", obj.Object.ObjectID))) + ft.AddTo(ioswitch2.NewToShardStore(*toStg, ioswitch2.RawStream(), fmt.Sprintf("%d.0", obj.Object.ObjectID))) planningHubIDs[solu.blockList[i].UserSpaceID] = true } @@ -810,10 +810,10 @@ func (t *ChangeRedundancy) makePlansForECObject(ctx *changeRedundancyContext, so // 依次生成每个节点上的执行计划,因为如果放到一个计划里一起生成,不能保证每个节点上的块用的都是本节点上的副本 ft := ioswitch2.NewFromTo() ft.ECParam = ecRed - ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *ctx.allUserSpaces[id].UserSpace.MasterHub, *ctx.allUserSpaces[id].UserSpace, ioswitch2.RawStream())) + ft.AddFrom(ioswitch2.NewFromShardstore(obj.Object.FileHash, *ctx.allUserSpaces[id].UserSpace, ioswitch2.RawStream())) for _, i := range *idxs { - ft.AddTo(ioswitch2.NewToShardStore(*ctx.allUserSpaces[id].UserSpace.MasterHub, *ctx.allUserSpaces[id].UserSpace, ioswitch2.ECStream(i), fmt.Sprintf("%d.%d", obj.Object.ObjectID, i))) + ft.AddTo(ioswitch2.NewToShardStore(*ctx.allUserSpaces[id].UserSpace, ioswitch2.ECStream(i), fmt.Sprintf("%d.%d", obj.Object.ObjectID, i))) } err := parser.Parse(ft, planBld) @@ -952,7 +952,7 @@ func (t *ChangeRedundancy) populateECObjectEntry(entry *db.UpdatingObjectRedunda key := fmt.Sprintf("%d.%d", obj.Object.ObjectID, entry.Blocks[i].Index) // 不应该出现key不存在的情况 - r := ioRets[key].(*ops2.ShardInfoValue) + r := ioRets[key].(*ops2.FileInfoValue) entry.Blocks[i].FileHash = r.Hash entry.Blocks[i].Size = r.Size } diff --git a/client/internal/ticktock/shardstore_gc.go b/client/internal/ticktock/shardstore_gc.go index 0934fe5..5ab4c04 100644 --- a/client/internal/ticktock/shardstore_gc.go +++ b/client/internal/ticktock/shardstore_gc.go @@ -87,11 +87,11 @@ func (j *ShardStoreGC) gcOne(t *TickTock, space *types.UserSpaceDetail) error { } // 获取与节点通信的代理客户端 - addr, ok := space.MasterHub.Address.(*cortypes.GRPCAddressInfo) + addr, ok := space.RecommendHub.Address.(*cortypes.GRPCAddressInfo) if !ok { return fmt.Errorf("master of user space %v has no grpc address", space.UserSpace) } - agtCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(space.MasterHub, addr)) + agtCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(&space.RecommendHub, addr)) defer agtCli.Release() // 向代理发送垃圾回收请求 diff --git a/client/internal/uploader/create_load.go b/client/internal/uploader/create_load.go index 5b92b78..ba0a56f 100644 --- a/client/internal/uploader/create_load.go +++ b/client/internal/uploader/create_load.go @@ -49,8 +49,8 @@ func (u *CreateUploader) Upload(pa string, stream io.Reader, opts ...UploadOptio fromExec, hd := ioswitch2.NewFromDriver(ioswitch2.RawStream()) ft.AddFrom(fromExec) for i, space := range u.targetSpaces { - ft.AddTo(ioswitch2.NewToShardStore(*space.MasterHub, space, ioswitch2.RawStream(), "shardInfo")) - ft.AddTo(ioswitch2.NewToPublicStore(*space.MasterHub, space, path.Join(u.copyRoots[i], pa))) + ft.AddTo(ioswitch2.NewToShardStore(space, ioswitch2.RawStream(), "shardInfo")) + ft.AddTo(ioswitch2.NewToBaseStore(space, path.Join(u.copyRoots[i], pa))) spaceIDs = append(spaceIDs, space.UserSpace.UserSpaceID) } @@ -73,7 +73,7 @@ func (u *CreateUploader) Upload(pa string, stream io.Reader, opts ...UploadOptio defer u.lock.Unlock() // 记录上传结果 - shardInfo := ret["fileHash"].(*ops2.ShardInfoValue) + shardInfo := ret["fileHash"].(*ops2.FileInfoValue) u.successes = append(u.successes, db.AddObjectEntry{ Path: pa, Size: shardInfo.Size, diff --git a/client/internal/uploader/update.go b/client/internal/uploader/update.go index 7e81bd6..eb3e168 100644 --- a/client/internal/uploader/update.go +++ b/client/internal/uploader/update.go @@ -58,10 +58,10 @@ func (w *UpdateUploader) Upload(pat string, stream io.Reader, opts ...UploadOpti ft := ioswitch2.NewFromTo() fromExec, hd := ioswitch2.NewFromDriver(ioswitch2.RawStream()) ft.AddFrom(fromExec). - AddTo(ioswitch2.NewToShardStore(*w.targetSpace.MasterHub, w.targetSpace, ioswitch2.RawStream(), "shardInfo")) + AddTo(ioswitch2.NewToShardStore(w.targetSpace, ioswitch2.RawStream(), "shardInfo")) for i, space := range w.copyToSpaces { - ft.AddTo(ioswitch2.NewToPublicStore(*space.MasterHub, space, path.Join(w.copyToPath[i], pat))) + ft.AddTo(ioswitch2.NewToBaseStore(space, path.Join(w.copyToPath[i], pat))) } plans := exec.NewPlanBuilder() @@ -83,7 +83,7 @@ func (w *UpdateUploader) Upload(pat string, stream io.Reader, opts ...UploadOpti defer w.lock.Unlock() // 记录上传结果 - shardInfo := ret["shardInfo"].(*ops2.ShardInfoValue) + shardInfo := ret["shardInfo"].(*ops2.FileInfoValue) w.successes = append(w.successes, db.AddObjectEntry{ Path: pat, Size: shardInfo.Size, diff --git a/client/internal/uploader/uploader.go b/client/internal/uploader/uploader.go index 5bd7d2f..dab1aad 100644 --- a/client/internal/uploader/uploader.go +++ b/client/internal/uploader/uploader.go @@ -55,13 +55,9 @@ func (u *Uploader) BeginUpdate(pkgID clitypes.PackageID, affinity clitypes.UserS cons := u.connectivity.GetAll() var uploadSpaces []UploadSpaceInfo for _, space := range spaceDetails { - if space.MasterHub == nil { - continue - } - latency := time.Duration(math.MaxInt64) - con, ok := cons[space.MasterHub.HubID] + con, ok := cons[space.RecommendHub.HubID] if ok && con.Latency != nil { latency = *con.Latency } @@ -69,7 +65,7 @@ func (u *Uploader) BeginUpdate(pkgID clitypes.PackageID, affinity clitypes.UserS uploadSpaces = append(uploadSpaces, UploadSpaceInfo{ Space: *space, Delay: latency, - IsSameLocation: space.MasterHub.LocationID == stgglb.Local.LocationID, + IsSameLocation: space.RecommendHub.LocationID == stgglb.Local.LocationID, }) } @@ -85,9 +81,6 @@ func (u *Uploader) BeginUpdate(pkgID clitypes.PackageID, affinity clitypes.UserS if !ok { return nil, fmt.Errorf("user space %v not found", spaceID) } - if space.MasterHub == nil { - return nil, fmt.Errorf("user space %v has no master hub", spaceID) - } copyToSpaces[i] = *space } @@ -207,13 +200,9 @@ func (u *Uploader) UploadPart(objID clitypes.ObjectID, index int, stream io.Read cons := u.connectivity.GetAll() var userStgs []UploadSpaceInfo for _, space := range spaces { - if space.MasterHub == nil { - continue - } - delay := time.Duration(math.MaxInt64) - con, ok := cons[space.MasterHub.HubID] + con, ok := cons[space.RecommendHub.HubID] if ok && con.Latency != nil { delay = *con.Latency } @@ -221,7 +210,7 @@ func (u *Uploader) UploadPart(objID clitypes.ObjectID, index int, stream io.Read userStgs = append(userStgs, UploadSpaceInfo{ Space: *space, Delay: delay, - IsSameLocation: space.MasterHub.LocationID == stgglb.Local.LocationID, + IsSameLocation: space.RecommendHub.LocationID == stgglb.Local.LocationID, }) } @@ -241,7 +230,7 @@ func (u *Uploader) UploadPart(objID clitypes.ObjectID, index int, stream io.Read ft := ioswitch2.NewFromTo() fromDrv, hd := ioswitch2.NewFromDriver(ioswitch2.RawStream()) ft.AddFrom(fromDrv). - AddTo(ioswitch2.NewToShardStore(*space.MasterHub, space, ioswitch2.RawStream(), "shard")) + AddTo(ioswitch2.NewToShardStore(space, ioswitch2.RawStream(), "shard")) plans := exec.NewPlanBuilder() err = parser.Parse(ft, plans) @@ -258,7 +247,7 @@ func (u *Uploader) UploadPart(objID clitypes.ObjectID, index int, stream io.Read return fmt.Errorf("executing plan: %w", err) } - shardInfo := ret["shard"].(*ops2.ShardInfoValue) + shardInfo := ret["shard"].(*ops2.FileInfoValue) err = u.db.DoTx(func(tx db.SQLContext) error { return u.db.Object().AppendPart(tx, clitypes.ObjectBlock{ ObjectID: objID, diff --git a/client/internal/uploader/user_space_upload.go b/client/internal/uploader/user_space_upload.go index 78e2e78..ce32afb 100644 --- a/client/internal/uploader/user_space_upload.go +++ b/client/internal/uploader/user_space_upload.go @@ -26,9 +26,6 @@ func (u *Uploader) UserSpaceUpload(userSpaceID clitypes.UserSpaceID, rootPath st if srcSpace == nil { return nil, fmt.Errorf("user space %d not found", userSpaceID) } - if srcSpace.MasterHub == nil { - return nil, fmt.Errorf("master hub not found for user space %d", userSpaceID) - } pkg, err := db.DoTx01(u.db, func(tx db.SQLContext) (clitypes.Package, error) { _, err := u.db.Bucket().GetByID(tx, targetBktID) @@ -53,13 +50,13 @@ func (u *Uploader) UserSpaceUpload(userSpaceID clitypes.UserSpaceID, rootPath st spaceDetails := u.spaceMeta.GetMany(spaceIDs) spaceDetails = lo.Filter(spaceDetails, func(e *clitypes.UserSpaceDetail, i int) bool { - return e != nil && e.MasterHub != nil && e.UserSpace.ShardStore != nil + return e != nil && e.UserSpace.ShardStore != nil }) coorCli := stgglb.CoordinatorRPCPool.Get() defer coorCli.Release() - resp, cerr := coorCli.GetHubConnectivities(context.Background(), corrpc.ReqGetHubConnectivities([]cortypes.HubID{srcSpace.MasterHub.HubID})) + resp, cerr := coorCli.GetHubConnectivities(context.Background(), corrpc.ReqGetHubConnectivities([]cortypes.HubID{srcSpace.RecommendHub.HubID})) if cerr != nil { delPkg() return nil, fmt.Errorf("getting hub connectivities: %w", cerr.ToError()) @@ -72,13 +69,9 @@ func (u *Uploader) UserSpaceUpload(userSpaceID clitypes.UserSpaceID, rootPath st var uploadSpaces []UploadSpaceInfo for _, space := range spaceDetails { - if space.MasterHub == nil { - continue - } - latency := time.Duration(math.MaxInt64) - con, ok := cons[space.MasterHub.HubID] + con, ok := cons[space.RecommendHub.HubID] if ok && con.Latency != nil { latency = time.Duration(*con.Latency * float32(time.Millisecond)) } @@ -86,7 +79,7 @@ func (u *Uploader) UserSpaceUpload(userSpaceID clitypes.UserSpaceID, rootPath st uploadSpaces = append(uploadSpaces, UploadSpaceInfo{ Space: *space, Delay: latency, - IsSameLocation: space.MasterHub.LocationID == srcSpace.MasterHub.LocationID, + IsSameLocation: space.RecommendHub.LocationID == srcSpace.RecommendHub.LocationID, }) } @@ -97,27 +90,27 @@ func (u *Uploader) UserSpaceUpload(userSpaceID clitypes.UserSpaceID, rootPath st targetSapce := u.chooseUploadStorage(uploadSpaces, uploadAffinity) - addr, ok := srcSpace.MasterHub.Address.(*cortypes.GRPCAddressInfo) + addr, ok := srcSpace.RecommendHub.Address.(*cortypes.GRPCAddressInfo) if !ok { delPkg() return nil, fmt.Errorf("master of user space %v has no grpc address", srcSpace.UserSpace) } - srcHubCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(srcSpace.MasterHub, addr)) + srcHubCli := stgglb.HubRPCPool.Get(stgglb.SelectGRPCAddress(&srcSpace.RecommendHub, addr)) defer srcHubCli.Release() - listAllResp, cerr := srcHubCli.PublicStoreListAll(context.Background(), &hubrpc.PublicStoreListAll{ + listAllResp, cerr := srcHubCli.BaseStoreListAll(context.Background(), &hubrpc.BaseStoreListAll{ UserSpace: *srcSpace, Path: rootPath, }) if cerr != nil { delPkg() - return nil, fmt.Errorf("listing public store: %w", cerr.ToError()) + return nil, fmt.Errorf("listing base store: %w", cerr.ToError()) } - adds, err := u.uploadFromPublicStore(srcSpace, &targetSapce.Space, listAllResp.Entries, rootPath) + adds, err := u.uploadFromBaseStore(srcSpace, &targetSapce.Space, listAllResp.Entries, rootPath) if err != nil { delPkg() - return nil, fmt.Errorf("uploading from public store: %w", err) + return nil, fmt.Errorf("uploading from base store: %w", err) } _, err = db.DoTx21(u.db, u.db.Object().BatchAdd, pkg.PackageID, adds) @@ -129,7 +122,7 @@ func (u *Uploader) UserSpaceUpload(userSpaceID clitypes.UserSpaceID, rootPath st return &pkg, nil } -func (u *Uploader) uploadFromPublicStore(srcSpace *clitypes.UserSpaceDetail, targetSpace *clitypes.UserSpaceDetail, entries []types.PublicStoreEntry, rootPath string) ([]db.AddObjectEntry, error) { +func (u *Uploader) uploadFromBaseStore(srcSpace *clitypes.UserSpaceDetail, targetSpace *clitypes.UserSpaceDetail, entries []types.BaseStoreEntry, rootPath string) ([]db.AddObjectEntry, error) { ft := ioswitch2.FromTo{} for _, e := range entries { @@ -138,8 +131,8 @@ func (u *Uploader) uploadFromPublicStore(srcSpace *clitypes.UserSpaceDetail, tar continue } - ft.AddFrom(ioswitch2.NewFromPublicStore(*srcSpace.MasterHub, *srcSpace, e.Path)) - ft.AddTo(ioswitch2.NewToShardStore(*targetSpace.MasterHub, *targetSpace, ioswitch2.RawStream(), e.Path)) + ft.AddFrom(ioswitch2.NewFromBaseStore(*srcSpace, e.Path)) + ft.AddTo(ioswitch2.NewToShardStore(*targetSpace, ioswitch2.RawStream(), e.Path)) } plans := exec.NewPlanBuilder() @@ -167,7 +160,7 @@ func (u *Uploader) uploadFromPublicStore(srcSpace *clitypes.UserSpaceDetail, tar pat = clitypes.BaseName(e.Path) } - info := ret[e.Path].(*ops2.ShardInfoValue) + info := ret[e.Path].(*ops2.FileInfoValue) adds = append(adds, db.AddObjectEntry{ Path: pat, Size: info.Size, diff --git a/client/types/types.go b/client/types/types.go index f5f829a..8431f9f 100644 --- a/client/types/types.go +++ b/client/types/types.go @@ -74,12 +74,14 @@ type UserSpace struct { UserSpaceID UserSpaceID `gorm:"column:UserSpaceID; primaryKey; type:bigint" json:"userSpaceID"` // 用户空间名称 Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` - // 用户空间所在的存储节点 - StorageID cotypes.StorageID `gorm:"column:StorageID; type:bigint; not null" json:"storageID"` + // 用户空间所在的存储服务配置 + Storage cotypes.StorageType `gorm:"column:Storage; type:json; not null; serializer:union" json:"storage"` // 用户在指定存储节点的凭证信息,比如用户账户,AK/SK等 Credential cotypes.StorageCredential `gorm:"column:Credential; type:json; not null; serializer:union" json:"credential"` // 用户空间的分片存储配置,如果为空,则表示不使用分片存储 ShardStore *cotypes.ShardStoreUserConfig `gorm:"column:ShardStore; type:json; serializer:json" json:"shardStore"` + // 存储服务特性功能的配置 + Features []cotypes.StorageFeature `json:"features" gorm:"column:Features; type:json; serializer:union"` // 用户空间信息的版本号,每一次更改都需要更新版本号 Revision int64 `gorm:"column:Revision; type:bigint; not null" json:"revision"` } @@ -89,7 +91,7 @@ func (UserSpace) TableName() string { } func (s UserSpace) String() string { - return fmt.Sprintf("%v[id=%v,storageID=%v,rev=%v]", s.Name, s.UserSpaceID, s.StorageID, s.Revision) + return fmt.Sprintf("%v[id=%v,storage=%v,rev=%v]", s.Name, s.UserSpaceID, s.Storage, s.Revision) } type PackageAccessStat struct { @@ -214,10 +216,9 @@ func (o *ObjectDetail) GroupBlocks() []GrouppedObjectBlock { } type UserSpaceDetail struct { - UserID cotypes.UserID - UserSpace UserSpace - Storage cotypes.Storage - MasterHub *cotypes.Hub + UserID cotypes.UserID + UserSpace UserSpace + RecommendHub cotypes.Hub } func (d UserSpaceDetail) String() string { diff --git a/common/pkgs/ioswitch2/fromto.go b/common/pkgs/ioswitch2/fromto.go index 43db703..aa8d186 100644 --- a/common/pkgs/ioswitch2/fromto.go +++ b/common/pkgs/ioswitch2/fromto.go @@ -4,7 +4,6 @@ import ( "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" "gitlink.org.cn/cloudream/common/utils/math2" clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types" - cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" ) type From interface { @@ -111,15 +110,13 @@ func (f *FromDriver) GetStreamIndex() StreamIndex { type FromShardstore struct { FileHash clitypes.FileHash - Hub cortypes.Hub UserSpace clitypes.UserSpaceDetail StreamIndex StreamIndex } -func NewFromShardstore(fileHash clitypes.FileHash, hub cortypes.Hub, space clitypes.UserSpaceDetail, strIdx StreamIndex) *FromShardstore { +func NewFromShardstore(fileHash clitypes.FileHash, space clitypes.UserSpaceDetail, strIdx StreamIndex) *FromShardstore { return &FromShardstore{ FileHash: fileHash, - Hub: hub, UserSpace: space, StreamIndex: strIdx, } @@ -129,21 +126,19 @@ func (f *FromShardstore) GetStreamIndex() StreamIndex { return f.StreamIndex } -type FromPublicStore struct { - Hub cortypes.Hub +type FromBaseStore struct { UserSpace clitypes.UserSpaceDetail Path string } -func NewFromPublicStore(hub cortypes.Hub, space clitypes.UserSpaceDetail, path string) *FromPublicStore { - return &FromPublicStore{ - Hub: hub, +func NewFromBaseStore(space clitypes.UserSpaceDetail, path string) *FromBaseStore { + return &FromBaseStore{ UserSpace: space, Path: path, } } -func (f *FromPublicStore) GetStreamIndex() StreamIndex { +func (f *FromBaseStore) GetStreamIndex() StreamIndex { return StreamIndex{ Type: StreamIndexRaw, } @@ -181,25 +176,22 @@ func (t *ToDriver) GetRange() math2.Range { } type ToShardStore struct { - Hub cortypes.Hub Space clitypes.UserSpaceDetail StreamIndex StreamIndex Range math2.Range FileHashStoreKey string } -func NewToShardStore(hub cortypes.Hub, space clitypes.UserSpaceDetail, strIdx StreamIndex, fileHashStoreKey string) *ToShardStore { +func NewToShardStore(space clitypes.UserSpaceDetail, strIdx StreamIndex, fileHashStoreKey string) *ToShardStore { return &ToShardStore{ - Hub: hub, Space: space, StreamIndex: strIdx, FileHashStoreKey: fileHashStoreKey, } } -func NewToShardStoreWithRange(hub cortypes.Hub, space clitypes.UserSpaceDetail, streamIndex StreamIndex, fileHashStoreKey string, rng math2.Range) *ToShardStore { +func NewToShardStoreWithRange(space clitypes.UserSpaceDetail, streamIndex StreamIndex, fileHashStoreKey string, rng math2.Range) *ToShardStore { return &ToShardStore{ - Hub: hub, Space: space, StreamIndex: streamIndex, FileHashStoreKey: fileHashStoreKey, @@ -215,26 +207,24 @@ func (t *ToShardStore) GetRange() math2.Range { return t.Range } -type ToPublicStore struct { - Hub cortypes.Hub +type ToBaseStore struct { Space clitypes.UserSpaceDetail ObjectPath string } -func NewToPublicStore(hub cortypes.Hub, space clitypes.UserSpaceDetail, objectPath string) *ToPublicStore { - return &ToPublicStore{ - Hub: hub, +func NewToBaseStore(space clitypes.UserSpaceDetail, objectPath string) *ToBaseStore { + return &ToBaseStore{ Space: space, ObjectPath: objectPath, } } -func (t *ToPublicStore) GetStreamIndex() StreamIndex { +func (t *ToBaseStore) GetStreamIndex() StreamIndex { return StreamIndex{ Type: StreamIndexRaw, } } -func (t *ToPublicStore) GetRange() math2.Range { +func (t *ToBaseStore) GetRange() math2.Range { return math2.Range{} } diff --git a/common/pkgs/ioswitch2/ops2/bypass.go b/common/pkgs/ioswitch2/ops2/bypass.go index c6ab107..18fbb7e 100644 --- a/common/pkgs/ioswitch2/ops2/bypass.go +++ b/common/pkgs/ioswitch2/ops2/bypass.go @@ -12,13 +12,13 @@ import ( func init() { exec.UseOp[*BypassToShardStore]() - exec.UseOp[*BypassToPublicStore]() + exec.UseOp[*BypassToBaseStore]() exec.UseVarValue[*BypassedFileInfoValue]() exec.UseVarValue[*BypassHandleResultValue]() exec.UseOp[*BypassFromShardStore]() - exec.UseOp[*BypassFromPublicStore]() + exec.UseOp[*BypassFromBaseStore]() exec.UseVarValue[*BypassFilePathValue]() exec.UseOp[*BypassFromShardStoreHTTP]() @@ -79,7 +79,7 @@ func (o *BypassToShardStore) Execute(ctx *exec.ExecContext, e *exec.Executor) er } e.PutVar(o.BypassCallback, &BypassHandleResultValue{Commited: true}) - e.PutVar(o.FileInfo, &ShardInfoValue{Hash: fileInfo.Hash, Size: fileInfo.Size}) + e.PutVar(o.FileInfo, &FileInfoValue{Hash: fileInfo.Hash, Size: fileInfo.Size}) return nil } @@ -87,27 +87,27 @@ func (o *BypassToShardStore) String() string { return fmt.Sprintf("BypassToShardStore[UserSpace:%v] Info: %v, Callback: %v", o.UserSpace, o.BypassFileInfo, o.BypassCallback) } -type BypassToPublicStore struct { +type BypassToBaseStore struct { UserSpace clitypes.UserSpaceDetail BypassFileInfo exec.VarID BypassCallback exec.VarID DestPath string } -func (o *BypassToPublicStore) Execute(ctx *exec.ExecContext, e *exec.Executor) error { +func (o *BypassToBaseStore) Execute(ctx *exec.ExecContext, e *exec.Executor) error { stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return err } - store, err := stgPool.GetPublicStore(&o.UserSpace) + store, err := stgPool.GetBaseStore(&o.UserSpace) if err != nil { return err } br, ok := store.(types.BypassPublicWrite) if !ok { - return fmt.Errorf("public store %v not support bypass write", o.UserSpace) + return fmt.Errorf("base store %v not support bypass write", o.UserSpace) } fileInfo, err := exec.BindVar[*BypassedFileInfoValue](e, ctx.Context, o.BypassFileInfo) @@ -124,8 +124,8 @@ func (o *BypassToPublicStore) Execute(ctx *exec.ExecContext, e *exec.Executor) e return nil } -func (o *BypassToPublicStore) String() string { - return fmt.Sprintf("BypassToPublicStore[UserSpace:%v] Info: %v, Callback: %v", o.UserSpace, o.BypassFileInfo, o.BypassCallback) +func (o *BypassToBaseStore) String() string { + return fmt.Sprintf("BypassToBaseStore[UserSpace:%v] Info: %v, Callback: %v", o.UserSpace, o.BypassFileInfo, o.BypassCallback) } type BypassFilePathValue struct { @@ -173,26 +173,26 @@ func (o *BypassFromShardStore) String() string { return fmt.Sprintf("BypassFromShardStore[UserSpace:%v] FileHash: %v, Output: %v", o.UserSpace, o.FileHash, o.Output) } -type BypassFromPublicStore struct { +type BypassFromBaseStore struct { UserSpace clitypes.UserSpaceDetail Path string Output exec.VarID } -func (o *BypassFromPublicStore) Execute(ctx *exec.ExecContext, e *exec.Executor) error { +func (o *BypassFromBaseStore) Execute(ctx *exec.ExecContext, e *exec.Executor) error { stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return err } - store, err := stgPool.GetPublicStore(&o.UserSpace) + store, err := stgPool.GetBaseStore(&o.UserSpace) if err != nil { return err } br, ok := store.(types.BypassPublicRead) if !ok { - return fmt.Errorf("public store %v not support bypass read", o.UserSpace) + return fmt.Errorf("base store %v not support bypass read", o.UserSpace) } path, err := br.BypassPublicRead(o.Path) @@ -204,8 +204,8 @@ func (o *BypassFromPublicStore) Execute(ctx *exec.ExecContext, e *exec.Executor) return nil } -func (o *BypassFromPublicStore) String() string { - return fmt.Sprintf("BypassFromPublicStore[UserSpace:%v] Path: %v, Output: %v", o.UserSpace, o.Path, o.Output) +func (o *BypassFromBaseStore) String() string { + return fmt.Sprintf("BypassFromBaseStore[UserSpace:%v] Path: %v, Output: %v", o.UserSpace, o.Path, o.Output) } // 旁路Http读取 @@ -303,14 +303,14 @@ func (t *BypassToShardStoreNode) GenerateOp() (exec.Op, error) { }, nil } -type BypassToPublicStoreNode struct { +type BypassToBaseStoreNode struct { dag.NodeBase UserSpace clitypes.UserSpaceDetail DestPath string } -func (b *GraphNodeBuilder) NewBypassToPublicStore(userSpace clitypes.UserSpaceDetail, dstPath string) *BypassToPublicStoreNode { - node := &BypassToPublicStoreNode{ +func (b *GraphNodeBuilder) NewBypassToBaseStore(userSpace clitypes.UserSpaceDetail, dstPath string) *BypassToBaseStoreNode { + node := &BypassToBaseStoreNode{ UserSpace: userSpace, DestPath: dstPath, } @@ -321,22 +321,22 @@ func (b *GraphNodeBuilder) NewBypassToPublicStore(userSpace clitypes.UserSpaceDe return node } -func (n *BypassToPublicStoreNode) BypassFileInfoSlot() dag.ValueInputSlot { +func (n *BypassToBaseStoreNode) BypassFileInfoSlot() dag.ValueInputSlot { return dag.ValueInputSlot{ Node: n, Index: 0, } } -func (n *BypassToPublicStoreNode) BypassCallbackVar() dag.ValueOutputSlot { +func (n *BypassToBaseStoreNode) BypassCallbackVar() dag.ValueOutputSlot { return dag.ValueOutputSlot{ Node: n, Index: 0, } } -func (t *BypassToPublicStoreNode) GenerateOp() (exec.Op, error) { - return &BypassToPublicStore{ +func (t *BypassToBaseStoreNode) GenerateOp() (exec.Op, error) { + return &BypassToBaseStore{ UserSpace: t.UserSpace, BypassFileInfo: t.BypassFileInfoSlot().Var().VarID, BypassCallback: t.BypassCallbackVar().Var().VarID, @@ -377,14 +377,14 @@ func (n *BypassFromShardStoreNode) GenerateOp() (exec.Op, error) { }, nil } -type BypassFromPublicStoreNode struct { +type BypassFromBaseStoreNode struct { dag.NodeBase UserSpace clitypes.UserSpaceDetail Path string } -func (b *GraphNodeBuilder) NewBypassFromPublicStore(userSpace clitypes.UserSpaceDetail, path string) *BypassFromPublicStoreNode { - node := &BypassFromPublicStoreNode{ +func (b *GraphNodeBuilder) NewBypassFromBaseStore(userSpace clitypes.UserSpaceDetail, path string) *BypassFromBaseStoreNode { + node := &BypassFromBaseStoreNode{ UserSpace: userSpace, Path: path, } @@ -394,15 +394,15 @@ func (b *GraphNodeBuilder) NewBypassFromPublicStore(userSpace clitypes.UserSpace return node } -func (n *BypassFromPublicStoreNode) FilePathVar() dag.ValueOutputSlot { +func (n *BypassFromBaseStoreNode) FilePathVar() dag.ValueOutputSlot { return dag.ValueOutputSlot{ Node: n, Index: 0, } } -func (n *BypassFromPublicStoreNode) GenerateOp() (exec.Op, error) { - return &BypassFromPublicStore{ +func (n *BypassFromBaseStoreNode) GenerateOp() (exec.Op, error) { + return &BypassFromBaseStore{ UserSpace: n.UserSpace, Path: n.Path, Output: n.FilePathVar().Var().VarID, diff --git a/common/pkgs/ioswitch2/ops2/public_store.go b/common/pkgs/ioswitch2/ops2/public_store.go index 235ed31..6e5a293 100644 --- a/common/pkgs/ioswitch2/ops2/public_store.go +++ b/common/pkgs/ioswitch2/ops2/public_store.go @@ -15,37 +15,47 @@ import ( ) func init() { - exec.UseOp[*PublicWrite]() - exec.UseOp[*PublicRead]() + exec.UseOp[*BaseWrite]() + exec.UseOp[*BaseRead]() + exec.UseVarValue[*FileInfoValue]() } -type PublicRead struct { - Output exec.VarID - UserSpace clitypes.UserSpaceDetail - ObjectPath string +type FileInfoValue struct { + Hash clitypes.FileHash `json:"hash"` + Size int64 `json:"size"` } -func (o *PublicRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error { +func (v *FileInfoValue) Clone() exec.VarValue { + return &FileInfoValue{Hash: v.Hash, Size: v.Size} +} + +type BaseRead struct { + Output exec.VarID + UserSpace clitypes.UserSpaceDetail + Path string +} + +func (o *BaseRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error { logger. WithField("Output", o.Output). WithField("UserSpace", o.UserSpace). - WithField("ObjectPath", o.ObjectPath). - Debug("public read") - defer logger.Debug("public read end") + WithField("Path", o.Path). + Debug("base read") + defer logger.Debug("base read end") stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return fmt.Errorf("getting storage pool: %w", err) } - store, err := stgPool.GetPublicStore(&o.UserSpace) + store, err := stgPool.GetBaseStore(&o.UserSpace) if err != nil { - return fmt.Errorf("getting public store of storage %v: %w", o.UserSpace, err) + return fmt.Errorf("getting base store of storage %v: %w", o.UserSpace, err) } - stream, err := store.Read(o.ObjectPath) + stream, err := store.Read(o.Path) if err != nil { - return fmt.Errorf("reading object %v: %w", o.ObjectPath, err) + return fmt.Errorf("reading object %v: %w", o.Path, err) } fut := future.NewSetVoid() @@ -59,30 +69,31 @@ func (o *PublicRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error { return fut.Wait(ctx.Context) } -func (o *PublicRead) String() string { - return fmt.Sprintf("PublicRead %v:%v -> %v", o.UserSpace, o.ObjectPath, o.Output) +func (o *BaseRead) String() string { + return fmt.Sprintf("PublicRead %v:%v -> %v", o.UserSpace, o.Path, o.Output) } -type PublicWrite struct { - Input exec.VarID - UserSpace clitypes.UserSpaceDetail - ObjectPath string +type BaseWrite struct { + Input exec.VarID + UserSpace clitypes.UserSpaceDetail + Path string + FileInfo exec.VarID } -func (o *PublicWrite) Execute(ctx *exec.ExecContext, e *exec.Executor) error { +func (o *BaseWrite) Execute(ctx *exec.ExecContext, e *exec.Executor) error { logger. WithField("Input", o.Input). - Debugf("write file to public store") - defer logger.Debugf("write file to public store finished") + Debugf("write file to base store") + defer logger.Debugf("write file to base store finished") stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return fmt.Errorf("getting storage pool: %w", err) } - store, err := stgPool.GetPublicStore(&o.UserSpace) + store, err := stgPool.GetBaseStore(&o.UserSpace) if err != nil { - return fmt.Errorf("getting public store of storage %v: %w", o.UserSpace, err) + return fmt.Errorf("getting base store of storage %v: %w", o.UserSpace, err) } input, err := exec.BindVar[*exec.StreamValue](e, ctx.Context, o.Input) @@ -91,25 +102,34 @@ func (o *PublicWrite) Execute(ctx *exec.ExecContext, e *exec.Executor) error { } defer input.Stream.Close() - return store.Write(o.ObjectPath, input.Stream) + info, err := store.Write(o.Path, input.Stream) + if err != nil { + return err + } + + e.PutVar(o.FileInfo, &FileInfoValue{ + Hash: info.Hash, + Size: info.Size, + }) + return nil } -func (o *PublicWrite) String() string { - return fmt.Sprintf("PublicWrite %v -> %v:%v", o.Input, o.UserSpace, o.ObjectPath) +func (o *BaseWrite) String() string { + return fmt.Sprintf("PublicWrite %v -> %v:%v", o.Input, o.UserSpace, o.Path) } -type PublicReadNode struct { +type BaseReadNode struct { dag.NodeBase - From ioswitch2.From - UserSpace clitypes.UserSpaceDetail - ObjectPath string + From ioswitch2.From + UserSpace clitypes.UserSpaceDetail + Path string } -func (b *GraphNodeBuilder) NewPublicRead(from ioswitch2.From, userSpace clitypes.UserSpaceDetail, objPath string) *PublicReadNode { - node := &PublicReadNode{ - From: from, - UserSpace: userSpace, - ObjectPath: objPath, +func (b *GraphNodeBuilder) NewPublicRead(from ioswitch2.From, userSpace clitypes.UserSpaceDetail, path string) *BaseReadNode { + node := &BaseReadNode{ + From: from, + UserSpace: userSpace, + Path: path, } b.AddNode(node) @@ -117,37 +137,38 @@ func (b *GraphNodeBuilder) NewPublicRead(from ioswitch2.From, userSpace clitypes return node } -func (t *PublicReadNode) GetFrom() ioswitch2.From { +func (t *BaseReadNode) GetFrom() ioswitch2.From { return t.From } -func (t *PublicReadNode) Output() dag.StreamOutputSlot { +func (t *BaseReadNode) Output() dag.StreamOutputSlot { return dag.StreamOutputSlot{ Node: t, Index: 0, } } -func (t *PublicReadNode) GenerateOp() (exec.Op, error) { - return &PublicRead{ - Output: t.Output().Var().VarID, - UserSpace: t.UserSpace, - ObjectPath: t.ObjectPath, +func (t *BaseReadNode) GenerateOp() (exec.Op, error) { + return &BaseRead{ + Output: t.Output().Var().VarID, + UserSpace: t.UserSpace, + Path: t.Path, }, nil } -type PublicWriteNode struct { +type BaseWriteNode struct { dag.NodeBase - To ioswitch2.To - UserSpace clitypes.UserSpaceDetail - ObjectPath string + To ioswitch2.To + UserSpace clitypes.UserSpaceDetail + Path string + FileInfoStoreKey string } -func (b *GraphNodeBuilder) NewPublicWrite(to ioswitch2.To, userSpace clitypes.UserSpaceDetail, objPath string) *PublicWriteNode { - node := &PublicWriteNode{ - To: to, - UserSpace: userSpace, - ObjectPath: objPath, +func (b *GraphNodeBuilder) NewPublicWrite(to ioswitch2.To, userSpace clitypes.UserSpaceDetail, path string) *BaseWriteNode { + node := &BaseWriteNode{ + To: to, + UserSpace: userSpace, + Path: path, } b.AddNode(node) @@ -155,25 +176,30 @@ func (b *GraphNodeBuilder) NewPublicWrite(to ioswitch2.To, userSpace clitypes.Us return node } -func (t *PublicWriteNode) GetTo() ioswitch2.To { +func (t *BaseWriteNode) GetTo() ioswitch2.To { return t.To } -func (t *PublicWriteNode) SetInput(input *dag.StreamVar) { +func (t *BaseWriteNode) SetInput(input *dag.StreamVar) { input.To(t, 0) } -func (t *PublicWriteNode) Input() dag.StreamInputSlot { +func (t *BaseWriteNode) Input() dag.StreamInputSlot { return dag.StreamInputSlot{ Node: t, Index: 0, } } -func (t *PublicWriteNode) GenerateOp() (exec.Op, error) { - return &PublicWrite{ - Input: t.InputStreams().Get(0).VarID, - UserSpace: t.UserSpace, - ObjectPath: t.ObjectPath, +func (t *BaseWriteNode) FileInfoVar() *dag.ValueVar { + return t.OutputValues().Get(0) +} + +func (t *BaseWriteNode) GenerateOp() (exec.Op, error) { + return &BaseWrite{ + Input: t.InputStreams().Get(0).VarID, + UserSpace: t.UserSpace, + Path: t.Path, + FileInfo: t.FileInfoVar().VarID, }, nil } diff --git a/common/pkgs/ioswitch2/ops2/s2s.go b/common/pkgs/ioswitch2/ops2/s2s.go index 74ce470..5247335 100644 --- a/common/pkgs/ioswitch2/ops2/s2s.go +++ b/common/pkgs/ioswitch2/ops2/s2s.go @@ -67,7 +67,7 @@ func (o *S2STransfer) Execute(ctx *exec.ExecContext, e *exec.Executor) error { } func (o *S2STransfer) String() string { - return fmt.Sprintf("S2STransfer %v:%v -> %v:%v, Callback: %v", o.Src.Storage.String(), o.SrcPath, o.Dst.Storage.String(), o.Output, o.BypassCallback) + return fmt.Sprintf("S2STransfer %v:%v -> %v:%v, Callback: %v", o.Src.UserSpace.Storage.String(), o.SrcPath, o.Dst.UserSpace.Storage.String(), o.Output, o.BypassCallback) } type S2STransferNode struct { diff --git a/common/pkgs/ioswitch2/ops2/shard_store.go b/common/pkgs/ioswitch2/ops2/shard_store.go index f7f970c..ae5408c 100644 --- a/common/pkgs/ioswitch2/ops2/shard_store.go +++ b/common/pkgs/ioswitch2/ops2/shard_store.go @@ -18,16 +18,6 @@ import ( func init() { exec.UseOp[*ShardRead]() exec.UseOp[*ShardWrite]() - exec.UseVarValue[*ShardInfoValue]() -} - -type ShardInfoValue struct { - Hash clitypes.FileHash `json:"hash"` - Size int64 `json:"size"` -} - -func (v *ShardInfoValue) Clone() exec.VarValue { - return &ShardInfoValue{Hash: v.Hash, Size: v.Size} } type ShardRead struct { @@ -105,7 +95,7 @@ func (o *ShardWrite) Execute(ctx *exec.ExecContext, e *exec.Executor) error { return fmt.Errorf("writing file to shard store: %w", err) } - e.PutVar(o.FileHashVar, &ShardInfoValue{ + e.PutVar(o.FileHashVar, &FileInfoValue{ Hash: fileInfo.Hash, Size: fileInfo.Size, }) diff --git a/common/pkgs/ioswitch2/parser/gen/generator.go b/common/pkgs/ioswitch2/parser/gen/generator.go index d1b1807..5601eab 100644 --- a/common/pkgs/ioswitch2/parser/gen/generator.go +++ b/common/pkgs/ioswitch2/parser/gen/generator.go @@ -286,13 +286,13 @@ func buildFromNode(ctx *state.GenerateState, f ioswitch2.From) (ops2.FromNode, e t.Open.WithNullableLength(openOff, &openLen) } - switch addr := f.Hub.Address.(type) { + switch addr := f.UserSpace.RecommendHub.Address.(type) { case *cortypes.HttpAddressInfo: - t.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: f.Hub}) + t.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: f.UserSpace.RecommendHub}) t.Env().Pinned = true case *cortypes.GRPCAddressInfo: - t.Env().ToEnvWorker(&ioswitch2.HubWorker{Hub: f.Hub, Address: *addr}) + t.Env().ToEnvWorker(&ioswitch2.HubWorker{Hub: f.UserSpace.RecommendHub, Address: *addr}) t.Env().Pinned = true default: @@ -336,16 +336,16 @@ func buildFromNode(ctx *state.GenerateState, f ioswitch2.From) (ops2.FromNode, e return n, nil - case *ioswitch2.FromPublicStore: + case *ioswitch2.FromBaseStore: // TODO 可以考虑支持设置读取范围 n := ctx.DAG.NewPublicRead(f, f.UserSpace, f.Path) - switch addr := f.Hub.Address.(type) { + switch addr := f.UserSpace.RecommendHub.Address.(type) { case *cortypes.HttpAddressInfo: - n.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: f.Hub}) + n.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: f.UserSpace.RecommendHub}) n.Env().Pinned = true case *cortypes.GRPCAddressInfo: - n.Env().ToEnvWorker(&ioswitch2.HubWorker{Hub: f.Hub, Address: *addr}) + n.Env().ToEnvWorker(&ioswitch2.HubWorker{Hub: f.UserSpace.RecommendHub, Address: *addr}) n.Env().Pinned = true default: @@ -364,7 +364,7 @@ func buildToNode(ctx *state.GenerateState, t ioswitch2.To) (ops2.ToNode, error) case *ioswitch2.ToShardStore: n := ctx.DAG.NewShardWrite(t, t.Space, t.FileHashStoreKey) - if err := setEnvByAddress(n, t.Hub, t.Hub.Address); err != nil { + if err := setEnvByAddress(n, t.Space.RecommendHub, t.Space.RecommendHub.Address); err != nil { return nil, err } @@ -379,10 +379,10 @@ func buildToNode(ctx *state.GenerateState, t ioswitch2.To) (ops2.ToNode, error) return n, nil - case *ioswitch2.ToPublicStore: + case *ioswitch2.ToBaseStore: n := ctx.DAG.NewPublicWrite(t, t.Space, t.ObjectPath) - if err := setEnvByAddress(n, t.Hub, t.Hub.Address); err != nil { + if err := setEnvByAddress(n, t.Space.RecommendHub, t.Space.RecommendHub.Address); err != nil { return nil, err } diff --git a/common/pkgs/ioswitch2/parser/opt/ec.go b/common/pkgs/ioswitch2/parser/opt/ec.go index 2cac839..aa4ad1e 100644 --- a/common/pkgs/ioswitch2/parser/opt/ec.go +++ b/common/pkgs/ioswitch2/parser/opt/ec.go @@ -69,7 +69,7 @@ func UseECMultiplier(ctx *state.GenerateState) { if to == nil { to = swNode.To - } else if to.Space.UserSpace.StorageID != swNode.UserSpace.UserSpace.StorageID { + } else if to.Space.UserSpace.Storage.Equals(swNode.UserSpace.UserSpace.Storage) { return true } swNodes = append(swNodes, swNode) @@ -97,13 +97,13 @@ func UseECMultiplier(ctx *state.GenerateState) { // 检查满足条件后,替换ECMultiply指令 callMul := ctx.DAG.NewCallECMultiplier(to.Space) - switch addr := to.Hub.Address.(type) { + switch addr := to.Space.RecommendHub.Address.(type) { case *cortypes.HttpAddressInfo: - callMul.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: to.Hub}) + callMul.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: to.Space.RecommendHub}) callMul.Env().Pinned = true case *cortypes.GRPCAddressInfo: - callMul.Env().ToEnvWorker(&ioswitch2.HubWorker{Hub: to.Hub, Address: *addr}) + callMul.Env().ToEnvWorker(&ioswitch2.HubWorker{Hub: to.Space.RecommendHub, Address: *addr}) callMul.Env().Pinned = true default: diff --git a/common/pkgs/ioswitch2/parser/opt/s2s.go b/common/pkgs/ioswitch2/parser/opt/s2s.go index bdd3348..a802a69 100644 --- a/common/pkgs/ioswitch2/parser/opt/s2s.go +++ b/common/pkgs/ioswitch2/parser/opt/s2s.go @@ -19,8 +19,8 @@ func UseS2STransfer(ctx *state.GenerateState) { switch fr := fr.(type) { case *ioswitch2.FromShardstore: s2sFromShardStore(ctx, fr, frNode) - case *ioswitch2.FromPublicStore: - s2sFromPublicStore(ctx, fr, frNode) + case *ioswitch2.FromBaseStore: + s2sFromBaseStore(ctx, fr, frNode) } } } @@ -44,7 +44,7 @@ func s2sFromShardStore(ctx *state.GenerateState, fromShard *ioswitch2.FromShards failed := false var toShards []*ops2.ShardWriteNode - var toPublics []*ops2.PublicWriteNode + var toPublics []*ops2.BaseWriteNode loop: for i := 0; i < outVar.Dst.Len(); i++ { @@ -65,7 +65,7 @@ loop: toShards = append(toShards, dstNode) - case *ops2.PublicWriteNode: + case *ops2.BaseWriteNode: dstStgBld := factory.GetBuilder(&dstNode.UserSpace) if !dstStgBld.FeatureDesc().HasBypassPublicWrite { failed = true @@ -112,7 +112,7 @@ loop: for _, toPub := range toPublics { s2sNode := ctx.DAG.NewS2STransfer(fromShard.UserSpace, toPub.UserSpace, types.S2SOption{ - DestPathHint: toPub.ObjectPath, + DestPathHint: toPub.Path, }) // 直传指令在目的地Hub上执行 s2sNode.Env().CopyFrom(toPub.Env()) @@ -123,7 +123,7 @@ loop: brNode.FilePathVar().ToSlot(s2sNode.SrcPathSlot()) // 传输结果通知目的节点 - bwNode := ctx.DAG.NewBypassToPublicStore(toPub.UserSpace, toPub.ObjectPath) + bwNode := ctx.DAG.NewBypassToBaseStore(toPub.UserSpace, toPub.Path) bwNode.Env().CopyFrom(toPub.Env()) s2sNode.BypassFileInfoVar().ToSlot(bwNode.BypassFileInfoSlot()) @@ -139,7 +139,7 @@ loop: delete(ctx.FromNodes, frNode.GetFrom()) } -func s2sFromPublicStore(ctx *state.GenerateState, fromPub *ioswitch2.FromPublicStore, frNode ops2.FromNode) { +func s2sFromBaseStore(ctx *state.GenerateState, fromPub *ioswitch2.FromBaseStore, frNode ops2.FromNode) { fromStgBld := factory.GetBuilder(&fromPub.UserSpace) if !fromStgBld.FeatureDesc().HasBypassPublicRead { return @@ -157,14 +157,14 @@ func s2sFromPublicStore(ctx *state.GenerateState, fromPub *ioswitch2.FromPublicS } failed := false - var toPublics []*ops2.PublicWriteNode + var toPublics []*ops2.BaseWriteNode loop: for i := 0; i < outVar.Dst.Len(); i++ { dstNode := outVar.Dst.Get(i) switch dstNode := dstNode.(type) { - case *ops2.PublicWriteNode: + case *ops2.BaseWriteNode: dstStgBld := factory.GetBuilder(&dstNode.UserSpace) if !dstStgBld.FeatureDesc().HasBypassPublicWrite { failed = true @@ -189,18 +189,18 @@ loop: for _, toPub := range toPublics { s2sNode := ctx.DAG.NewS2STransfer(fromPub.UserSpace, toPub.UserSpace, types.S2SOption{ - DestPathHint: toPub.ObjectPath, + DestPathHint: toPub.Path, }) // 直传指令在目的地Hub上执行 s2sNode.Env().CopyFrom(toPub.Env()) // 先获取文件路径,送到S2S节点 - brNode := ctx.DAG.NewBypassFromPublicStore(fromPub.UserSpace, fromPub.Path) + brNode := ctx.DAG.NewBypassFromBaseStore(fromPub.UserSpace, fromPub.Path) brNode.Env().CopyFrom(toPub.Env()) brNode.FilePathVar().ToSlot(s2sNode.SrcPathSlot()) // 传输结果通知目的节点 - bwNode := ctx.DAG.NewBypassToPublicStore(toPub.UserSpace, toPub.ObjectPath) + bwNode := ctx.DAG.NewBypassToBaseStore(toPub.UserSpace, toPub.Path) bwNode.Env().CopyFrom(toPub.Env()) s2sNode.BypassFileInfoVar().ToSlot(bwNode.BypassFileInfoSlot()) diff --git a/common/pkgs/ioswitch2/plans/complete_multipart.go b/common/pkgs/ioswitch2/plans/complete_multipart.go index d2cd88b..1fda5e6 100644 --- a/common/pkgs/ioswitch2/plans/complete_multipart.go +++ b/common/pkgs/ioswitch2/plans/complete_multipart.go @@ -16,12 +16,12 @@ func CompleteMultipart(blocks []clitypes.ObjectBlock, blockSpaces []clitypes.Use sizes[i] = blk.Size } joinNode := da.NewSegmentJoin(sizes) - joinNode.Env().ToEnvWorker(getWorkerInfo(*targetSpace.MasterHub)) + joinNode.Env().ToEnvWorker(getWorkerInfo(targetSpace.RecommendHub)) joinNode.Env().Pinned = true for i, blk := range blocks { rd := da.NewShardRead(nil, blockSpaces[i], types.NewOpen(blk.FileHash)) - rd.Env().ToEnvWorker(getWorkerInfo(*blockSpaces[i].MasterHub)) + rd.Env().ToEnvWorker(getWorkerInfo(blockSpaces[i].RecommendHub)) rd.Env().Pinned = true rd.Output().ToSlot(joinNode.InputSlot(i)) @@ -29,7 +29,7 @@ func CompleteMultipart(blocks []clitypes.ObjectBlock, blockSpaces []clitypes.Use // TODO 应该采取更合理的方式同时支持Parser和直接生成DAG wr := da.NewShardWrite(nil, targetSpace, shardInfoKey) - wr.Env().ToEnvWorker(getWorkerInfo(*targetSpace.MasterHub)) + wr.Env().ToEnvWorker(getWorkerInfo(targetSpace.RecommendHub)) wr.Env().Pinned = true joinNode.Joined().ToSlot(wr.Input()) diff --git a/common/pkgs/ioswitchlrc/fromto.go b/common/pkgs/ioswitchlrc/fromto.go index b93c496..66600e1 100644 --- a/common/pkgs/ioswitchlrc/fromto.go +++ b/common/pkgs/ioswitchlrc/fromto.go @@ -4,7 +4,6 @@ import ( "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" "gitlink.org.cn/cloudream/common/utils/math2" clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types" - cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" ) type From interface { @@ -40,15 +39,13 @@ func (f *FromDriver) GetDataIndex() int { type FromNode struct { FileHash clitypes.FileHash - Hub cortypes.Hub Space clitypes.UserSpaceDetail DataIndex int } -func NewFromStorage(fileHash clitypes.FileHash, hub cortypes.Hub, space clitypes.UserSpaceDetail, dataIndex int) *FromNode { +func NewFromStorage(fileHash clitypes.FileHash, space clitypes.UserSpaceDetail, dataIndex int) *FromNode { return &FromNode{ FileHash: fileHash, - Hub: hub, DataIndex: dataIndex, Space: space, } @@ -90,25 +87,22 @@ func (t *ToDriver) GetRange() math2.Range { } type ToNode struct { - Hub cortypes.Hub Space clitypes.UserSpaceDetail DataIndex int Range math2.Range FileHashStoreKey string } -func NewToStorage(hub cortypes.Hub, space clitypes.UserSpaceDetail, dataIndex int, fileHashStoreKey string) *ToNode { +func NewToStorage(space clitypes.UserSpaceDetail, dataIndex int, fileHashStoreKey string) *ToNode { return &ToNode{ - Hub: hub, Space: space, DataIndex: dataIndex, FileHashStoreKey: fileHashStoreKey, } } -func NewToStorageWithRange(hub cortypes.Hub, space clitypes.UserSpaceDetail, dataIndex int, fileHashStoreKey string, rng math2.Range) *ToNode { +func NewToStorageWithRange(space clitypes.UserSpaceDetail, dataIndex int, fileHashStoreKey string, rng math2.Range) *ToNode { return &ToNode{ - Hub: hub, Space: space, DataIndex: dataIndex, FileHashStoreKey: fileHashStoreKey, diff --git a/common/pkgs/ioswitchlrc/parser/passes.go b/common/pkgs/ioswitchlrc/parser/passes.go index c54bc00..27c5bc3 100644 --- a/common/pkgs/ioswitchlrc/parser/passes.go +++ b/common/pkgs/ioswitchlrc/parser/passes.go @@ -72,7 +72,7 @@ func buildFromNode(ctx *GenerateContext, f ioswitchlrc.From) (ops2.FromNode, err } // TODO2 支持HTTP协议 - t.Env().ToEnvWorker(&ioswitchlrc.HubWorker{Hub: f.Hub, Address: *f.Hub.Address.(*cortypes.GRPCAddressInfo)}) + t.Env().ToEnvWorker(&ioswitchlrc.HubWorker{Hub: f.Space.RecommendHub, Address: *f.Space.RecommendHub.Address.(*cortypes.GRPCAddressInfo)}) t.Env().Pinned = true return t, nil @@ -101,12 +101,12 @@ func buildToNode(ctx *GenerateContext, t ioswitchlrc.To) (ops2.ToNode, error) { switch t := t.(type) { case *ioswitchlrc.ToNode: n := ctx.DAG.NewShardWrite(t, t.Space, t.FileHashStoreKey) - switch addr := t.Hub.Address.(type) { + switch addr := t.Space.RecommendHub.Address.(type) { // case *cdssdk.HttpAddressInfo: // n.Env().ToEnvWorker(&ioswitchlrc.HttpHubWorker{Node: t.Hub}) // TODO2 支持HTTP协议 case *cortypes.GRPCAddressInfo: - n.Env().ToEnvWorker(&ioswitchlrc.HubWorker{Hub: t.Hub, Address: *addr}) + n.Env().ToEnvWorker(&ioswitchlrc.HubWorker{Hub: t.Space.RecommendHub, Address: *addr}) default: return nil, fmt.Errorf("unsupported node address type %T", addr) diff --git a/common/pkgs/rpc/coordinator/coordinator.pb.go b/common/pkgs/rpc/coordinator/coordinator.pb.go index 4767db5..183b676 100644 --- a/common/pkgs/rpc/coordinator/coordinator.pb.go +++ b/common/pkgs/rpc/coordinator/coordinator.pb.go @@ -27,7 +27,7 @@ var file_pkgs_rpc_coordinator_coordinator_proto_rawDesc = []byte{ 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x63, 0x6f, 0x72, 0x72, 0x70, 0x63, 0x1a, 0x12, 0x70, 0x6b, 0x67, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x70, 0x63, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xff, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xfe, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x48, 0x75, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, @@ -40,14 +40,14 @@ var file_pkgs_rpc_coordinator_coordinator_proto_rawDesc = []byte{ 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x75, 0x62, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x6c, 0x69, 0x6e, - 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x63, 0x6e, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, 0x65, - 0x61, 0x6d, 0x2f, 0x6a, 0x63, 0x73, 0x2d, 0x70, 0x75, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2f, 0x70, 0x6b, 0x67, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x72, 0x72, 0x70, - 0x63, 0x3b, 0x63, 0x6f, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x10, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x48, 0x75, 0x62, 0x12, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x6c, 0x69, 0x6e, 0x6b, + 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x63, 0x6e, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, 0x65, 0x61, + 0x6d, 0x2f, 0x6a, 0x63, 0x73, 0x2d, 0x70, 0x75, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2f, 0x70, 0x6b, 0x67, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x72, 0x72, 0x70, 0x63, + 0x3b, 0x63, 0x6f, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_pkgs_rpc_coordinator_coordinator_proto_goTypes = []any{ @@ -59,12 +59,12 @@ var file_pkgs_rpc_coordinator_coordinator_proto_depIdxs = []int32{ 0, // 1: corrpc.Coordinator.GetHubs:input_type -> rpc.Request 0, // 2: corrpc.Coordinator.GetHubConnectivities:input_type -> rpc.Request 0, // 3: corrpc.Coordinator.ReportHubConnectivity:input_type -> rpc.Request - 0, // 4: corrpc.Coordinator.GetStorageDetails:input_type -> rpc.Request + 0, // 4: corrpc.Coordinator.SelectStorageHub:input_type -> rpc.Request 1, // 5: corrpc.Coordinator.GetHubConfig:output_type -> rpc.Response 1, // 6: corrpc.Coordinator.GetHubs:output_type -> rpc.Response 1, // 7: corrpc.Coordinator.GetHubConnectivities:output_type -> rpc.Response 1, // 8: corrpc.Coordinator.ReportHubConnectivity:output_type -> rpc.Response - 1, // 9: corrpc.Coordinator.GetStorageDetails:output_type -> rpc.Response + 1, // 9: corrpc.Coordinator.SelectStorageHub:output_type -> rpc.Response 5, // [5:10] is the sub-list for method output_type 0, // [0:5] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name diff --git a/common/pkgs/rpc/coordinator/coordinator.proto b/common/pkgs/rpc/coordinator/coordinator.proto index 2910f7e..c4e565a 100644 --- a/common/pkgs/rpc/coordinator/coordinator.proto +++ b/common/pkgs/rpc/coordinator/coordinator.proto @@ -13,5 +13,5 @@ service Coordinator { rpc GetHubConnectivities(rpc.Request) returns(rpc.Response); rpc ReportHubConnectivity(rpc.Request) returns(rpc.Response); - rpc GetStorageDetails(rpc.Request) returns(rpc.Response); + rpc SelectStorageHub(rpc.Request) returns(rpc.Response); } \ No newline at end of file diff --git a/common/pkgs/rpc/coordinator/coordinator_grpc.pb.go b/common/pkgs/rpc/coordinator/coordinator_grpc.pb.go index e89ef19..93a7cf2 100644 --- a/common/pkgs/rpc/coordinator/coordinator_grpc.pb.go +++ b/common/pkgs/rpc/coordinator/coordinator_grpc.pb.go @@ -24,7 +24,7 @@ const ( Coordinator_GetHubs_FullMethodName = "/corrpc.Coordinator/GetHubs" Coordinator_GetHubConnectivities_FullMethodName = "/corrpc.Coordinator/GetHubConnectivities" Coordinator_ReportHubConnectivity_FullMethodName = "/corrpc.Coordinator/ReportHubConnectivity" - Coordinator_GetStorageDetails_FullMethodName = "/corrpc.Coordinator/GetStorageDetails" + Coordinator_SelectStorageHub_FullMethodName = "/corrpc.Coordinator/SelectStorageHub" ) // CoordinatorClient is the client API for Coordinator service. @@ -35,7 +35,7 @@ type CoordinatorClient interface { GetHubs(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) GetHubConnectivities(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) ReportHubConnectivity(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) - GetStorageDetails(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) + SelectStorageHub(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) } type coordinatorClient struct { @@ -82,9 +82,9 @@ func (c *coordinatorClient) ReportHubConnectivity(ctx context.Context, in *rpc.R return out, nil } -func (c *coordinatorClient) GetStorageDetails(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) { +func (c *coordinatorClient) SelectStorageHub(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) { out := new(rpc.Response) - err := c.cc.Invoke(ctx, Coordinator_GetStorageDetails_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Coordinator_SelectStorageHub_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -99,7 +99,7 @@ type CoordinatorServer interface { GetHubs(context.Context, *rpc.Request) (*rpc.Response, error) GetHubConnectivities(context.Context, *rpc.Request) (*rpc.Response, error) ReportHubConnectivity(context.Context, *rpc.Request) (*rpc.Response, error) - GetStorageDetails(context.Context, *rpc.Request) (*rpc.Response, error) + SelectStorageHub(context.Context, *rpc.Request) (*rpc.Response, error) mustEmbedUnimplementedCoordinatorServer() } @@ -119,8 +119,8 @@ func (UnimplementedCoordinatorServer) GetHubConnectivities(context.Context, *rpc func (UnimplementedCoordinatorServer) ReportHubConnectivity(context.Context, *rpc.Request) (*rpc.Response, error) { return nil, status.Errorf(codes.Unimplemented, "method ReportHubConnectivity not implemented") } -func (UnimplementedCoordinatorServer) GetStorageDetails(context.Context, *rpc.Request) (*rpc.Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetStorageDetails not implemented") +func (UnimplementedCoordinatorServer) SelectStorageHub(context.Context, *rpc.Request) (*rpc.Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method SelectStorageHub not implemented") } func (UnimplementedCoordinatorServer) mustEmbedUnimplementedCoordinatorServer() {} @@ -207,20 +207,20 @@ func _Coordinator_ReportHubConnectivity_Handler(srv interface{}, ctx context.Con return interceptor(ctx, in, info, handler) } -func _Coordinator_GetStorageDetails_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Coordinator_SelectStorageHub_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(rpc.Request) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(CoordinatorServer).GetStorageDetails(ctx, in) + return srv.(CoordinatorServer).SelectStorageHub(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Coordinator_GetStorageDetails_FullMethodName, + FullMethod: Coordinator_SelectStorageHub_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(CoordinatorServer).GetStorageDetails(ctx, req.(*rpc.Request)) + return srv.(CoordinatorServer).SelectStorageHub(ctx, req.(*rpc.Request)) } return interceptor(ctx, in, info, handler) } @@ -249,8 +249,8 @@ var Coordinator_ServiceDesc = grpc.ServiceDesc{ Handler: _Coordinator_ReportHubConnectivity_Handler, }, { - MethodName: "GetStorageDetails", - Handler: _Coordinator_GetStorageDetails_Handler, + MethodName: "SelectStorageHub", + Handler: _Coordinator_SelectStorageHub_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/common/pkgs/rpc/coordinator/storage.go b/common/pkgs/rpc/coordinator/storage.go index e623648..d6e4c4d 100644 --- a/common/pkgs/rpc/coordinator/storage.go +++ b/common/pkgs/rpc/coordinator/storage.go @@ -8,34 +8,23 @@ import ( ) type StorageService interface { - GetStorageDetails(ctx context.Context, msg *GetStorageDetails) (*GetStorageDetailsResp, *rpc.CodeError) + SelectStorageHub(ctx context.Context, msg *SelectStorageHub) (*SelectStorageHubResp, *rpc.CodeError) } -// 获取Storage信息 - -type GetStorageDetails struct { - StorageIDs []cortypes.StorageID `json:"storageIDs"` +// 为指定的Storage选择一个适合通信的Hub +type SelectStorageHub struct { + Storages []cortypes.StorageType } -type GetStorageDetailsResp struct { - Storage []*cortypes.StorageDetail `json:"storages"` +type SelectStorageHubResp struct { + Hubs []*cortypes.Hub } -func ReqGetStorageDetails(storageIDs []cortypes.StorageID) *GetStorageDetails { - return &GetStorageDetails{ - StorageIDs: storageIDs, - } -} -func RespGetStorageDetails(stgs []*cortypes.StorageDetail) *GetStorageDetailsResp { - return &GetStorageDetailsResp{ - Storage: stgs, - } -} -func (c *Client) GetStorageDetails(ctx context.Context, msg *GetStorageDetails) (*GetStorageDetailsResp, *rpc.CodeError) { +func (c *Client) SelectStorageHub(ctx context.Context, msg *SelectStorageHub) (*SelectStorageHubResp, *rpc.CodeError) { if c.fusedErr != nil { return nil, c.fusedErr } - return rpc.UnaryClient[*GetStorageDetailsResp](c.cli.GetStorageDetails, ctx, msg) + return rpc.UnaryClient[*SelectStorageHubResp](c.cli.SelectStorageHub, ctx, msg) } -func (s *Server) GetStorageDetails(ctx context.Context, msg *rpc.Request) (*rpc.Response, error) { - return rpc.UnaryServer(s.svrImpl.GetStorageDetails, ctx, msg) +func (s *Server) SelectStorageHub(ctx context.Context, msg *rpc.Request) (*rpc.Response, error) { + return rpc.UnaryServer(s.svrImpl.SelectStorageHub, ctx, msg) } diff --git a/common/pkgs/rpc/hub/hub.pb.go b/common/pkgs/rpc/hub/hub.pb.go index 52b2492..6d2921e 100644 --- a/common/pkgs/rpc/hub/hub.pb.go +++ b/common/pkgs/rpc/hub/hub.pb.go @@ -76,8 +76,8 @@ var file_pkgs_rpc_hub_hub_proto_depIdxs = []int32{ 0, // 2: hubrpc.Hub.GetIOStream:input_type -> rpc.Request 0, // 3: hubrpc.Hub.SendIOVar:input_type -> rpc.Request 0, // 4: hubrpc.Hub.GetIOVar:input_type -> rpc.Request - 0, // 5: hubrpc.Hub.PublicStoreListAll:input_type -> rpc.Request - 0, // 6: hubrpc.Hub.PublicStoreMkdirs:input_type -> rpc.Request + 0, // 5: hubrpc.Hub.BaseStoreListAll:input_type -> rpc.Request + 0, // 6: hubrpc.Hub.BaseStoreMkdirs:input_type -> rpc.Request 0, // 7: hubrpc.Hub.CheckCache:input_type -> rpc.Request 0, // 8: hubrpc.Hub.CacheGC:input_type -> rpc.Request 0, // 9: hubrpc.Hub.Ping:input_type -> rpc.Request @@ -87,8 +87,8 @@ var file_pkgs_rpc_hub_hub_proto_depIdxs = []int32{ 1, // 13: hubrpc.Hub.GetIOStream:output_type -> rpc.ChunkedData 2, // 14: hubrpc.Hub.SendIOVar:output_type -> rpc.Response 2, // 15: hubrpc.Hub.GetIOVar:output_type -> rpc.Response - 2, // 16: hubrpc.Hub.PublicStoreListAll:output_type -> rpc.Response - 2, // 17: hubrpc.Hub.PublicStoreMkdirs:output_type -> rpc.Response + 2, // 16: hubrpc.Hub.BaseStoreListAll:output_type -> rpc.Response + 2, // 17: hubrpc.Hub.BaseStoreMkdirs:output_type -> rpc.Response 2, // 18: hubrpc.Hub.CheckCache:output_type -> rpc.Response 2, // 19: hubrpc.Hub.CacheGC:output_type -> rpc.Response 2, // 20: hubrpc.Hub.Ping:output_type -> rpc.Response diff --git a/common/pkgs/rpc/hub/hub.proto b/common/pkgs/rpc/hub/hub.proto index 754a241..58d86c5 100644 --- a/common/pkgs/rpc/hub/hub.proto +++ b/common/pkgs/rpc/hub/hub.proto @@ -14,8 +14,8 @@ service Hub { rpc SendIOVar(rpc.Request)returns(rpc.Response); rpc GetIOVar(rpc.Request)returns(rpc.Response); - rpc PublicStoreListAll(rpc.Request) returns(rpc.Response); - rpc PublicStoreMkdirs(rpc.Request) returns(rpc.Response); + rpc BaseStoreListAll(rpc.Request) returns(rpc.Response); + rpc BaseStoreMkdirs(rpc.Request) returns(rpc.Response); rpc CheckCache(rpc.Request) returns(rpc.Response); rpc CacheGC(rpc.Request) returns(rpc.Response); diff --git a/common/pkgs/rpc/hub/hub_grpc.pb.go b/common/pkgs/rpc/hub/hub_grpc.pb.go index f7a2b95..075d899 100644 --- a/common/pkgs/rpc/hub/hub_grpc.pb.go +++ b/common/pkgs/rpc/hub/hub_grpc.pb.go @@ -25,8 +25,8 @@ const ( Hub_GetIOStream_FullMethodName = "/hubrpc.Hub/GetIOStream" Hub_SendIOVar_FullMethodName = "/hubrpc.Hub/SendIOVar" Hub_GetIOVar_FullMethodName = "/hubrpc.Hub/GetIOVar" - Hub_PublicStoreListAll_FullMethodName = "/hubrpc.Hub/PublicStoreListAll" - Hub_PublicStoreMkdirs_FullMethodName = "/hubrpc.Hub/PublicStoreMkdirs" + Hub_BaseStoreListAll_FullMethodName = "/hubrpc.Hub/BaseStoreListAll" + Hub_BaseStoreMkdirs_FullMethodName = "/hubrpc.Hub/BaseStoreMkdirs" Hub_CheckCache_FullMethodName = "/hubrpc.Hub/CheckCache" Hub_CacheGC_FullMethodName = "/hubrpc.Hub/CacheGC" Hub_Ping_FullMethodName = "/hubrpc.Hub/Ping" @@ -42,8 +42,8 @@ type HubClient interface { GetIOStream(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (Hub_GetIOStreamClient, error) SendIOVar(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) GetIOVar(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) - PublicStoreListAll(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) - PublicStoreMkdirs(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) + BaseStoreListAll(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) + BaseStoreMkdirs(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) CheckCache(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) CacheGC(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) Ping(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) @@ -151,18 +151,18 @@ func (c *hubClient) GetIOVar(ctx context.Context, in *rpc.Request, opts ...grpc. return out, nil } -func (c *hubClient) PublicStoreListAll(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) { +func (c *hubClient) BaseStoreListAll(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) { out := new(rpc.Response) - err := c.cc.Invoke(ctx, Hub_PublicStoreListAll_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Hub_BaseStoreListAll_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *hubClient) PublicStoreMkdirs(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) { +func (c *hubClient) BaseStoreMkdirs(ctx context.Context, in *rpc.Request, opts ...grpc.CallOption) (*rpc.Response, error) { out := new(rpc.Response) - err := c.cc.Invoke(ctx, Hub_PublicStoreMkdirs_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Hub_BaseStoreMkdirs_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -214,8 +214,8 @@ type HubServer interface { GetIOStream(*rpc.Request, Hub_GetIOStreamServer) error SendIOVar(context.Context, *rpc.Request) (*rpc.Response, error) GetIOVar(context.Context, *rpc.Request) (*rpc.Response, error) - PublicStoreListAll(context.Context, *rpc.Request) (*rpc.Response, error) - PublicStoreMkdirs(context.Context, *rpc.Request) (*rpc.Response, error) + BaseStoreListAll(context.Context, *rpc.Request) (*rpc.Response, error) + BaseStoreMkdirs(context.Context, *rpc.Request) (*rpc.Response, error) CheckCache(context.Context, *rpc.Request) (*rpc.Response, error) CacheGC(context.Context, *rpc.Request) (*rpc.Response, error) Ping(context.Context, *rpc.Request) (*rpc.Response, error) @@ -242,11 +242,11 @@ func (UnimplementedHubServer) SendIOVar(context.Context, *rpc.Request) (*rpc.Res func (UnimplementedHubServer) GetIOVar(context.Context, *rpc.Request) (*rpc.Response, error) { return nil, status.Errorf(codes.Unimplemented, "method GetIOVar not implemented") } -func (UnimplementedHubServer) PublicStoreListAll(context.Context, *rpc.Request) (*rpc.Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method PublicStoreListAll not implemented") +func (UnimplementedHubServer) BaseStoreListAll(context.Context, *rpc.Request) (*rpc.Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method BaseStoreListAll not implemented") } -func (UnimplementedHubServer) PublicStoreMkdirs(context.Context, *rpc.Request) (*rpc.Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method PublicStoreMkdirs not implemented") +func (UnimplementedHubServer) BaseStoreMkdirs(context.Context, *rpc.Request) (*rpc.Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method BaseStoreMkdirs not implemented") } func (UnimplementedHubServer) CheckCache(context.Context, *rpc.Request) (*rpc.Response, error) { return nil, status.Errorf(codes.Unimplemented, "method CheckCache not implemented") @@ -374,38 +374,38 @@ func _Hub_GetIOVar_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } -func _Hub_PublicStoreListAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Hub_BaseStoreListAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(rpc.Request) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(HubServer).PublicStoreListAll(ctx, in) + return srv.(HubServer).BaseStoreListAll(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Hub_PublicStoreListAll_FullMethodName, + FullMethod: Hub_BaseStoreListAll_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(HubServer).PublicStoreListAll(ctx, req.(*rpc.Request)) + return srv.(HubServer).BaseStoreListAll(ctx, req.(*rpc.Request)) } return interceptor(ctx, in, info, handler) } -func _Hub_PublicStoreMkdirs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Hub_BaseStoreMkdirs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(rpc.Request) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(HubServer).PublicStoreMkdirs(ctx, in) + return srv.(HubServer).BaseStoreMkdirs(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Hub_PublicStoreMkdirs_FullMethodName, + FullMethod: Hub_BaseStoreMkdirs_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(HubServer).PublicStoreMkdirs(ctx, req.(*rpc.Request)) + return srv.(HubServer).BaseStoreMkdirs(ctx, req.(*rpc.Request)) } return interceptor(ctx, in, info, handler) } @@ -502,12 +502,12 @@ var Hub_ServiceDesc = grpc.ServiceDesc{ Handler: _Hub_GetIOVar_Handler, }, { - MethodName: "PublicStoreListAll", - Handler: _Hub_PublicStoreListAll_Handler, + MethodName: "BaseStoreListAll", + Handler: _Hub_BaseStoreListAll_Handler, }, { - MethodName: "PublicStoreMkdirs", - Handler: _Hub_PublicStoreMkdirs_Handler, + MethodName: "BaseStoreMkdirs", + Handler: _Hub_BaseStoreMkdirs_Handler, }, { MethodName: "CheckCache", diff --git a/common/pkgs/rpc/hub/user_space.go b/common/pkgs/rpc/hub/user_space.go index 6faa940..add5b2a 100644 --- a/common/pkgs/rpc/hub/user_space.go +++ b/common/pkgs/rpc/hub/user_space.go @@ -9,45 +9,45 @@ import ( ) type UserSpaceSvc interface { - PublicStoreListAll(ctx context.Context, req *PublicStoreListAll) (*PublicStoreListAllResp, *rpc.CodeError) - PublicStoreMkdirs(ctx context.Context, req *PublicStoreMkdirs) (*PublicStoreMkdirsResp, *rpc.CodeError) + BaseStoreListAll(ctx context.Context, req *BaseStoreListAll) (*BaseStoreListAllResp, *rpc.CodeError) + BaseStoreMkdirs(ctx context.Context, req *BaseStoreMkdirs) (*BaseStoreMkdirsResp, *rpc.CodeError) } -// 列出指定PublicStore的指定位置内的所有文件 -type PublicStoreListAll struct { +// 列出指定BaseStore的指定位置内的所有文件 +type BaseStoreListAll struct { UserSpace clitypes.UserSpaceDetail Path string } -type PublicStoreListAllResp struct { - Entries []stgtypes.PublicStoreEntry +type BaseStoreListAllResp struct { + Entries []stgtypes.BaseStoreEntry } -func (c *Client) PublicStoreListAll(ctx context.Context, req *PublicStoreListAll) (*PublicStoreListAllResp, *rpc.CodeError) { +func (c *Client) BaseStoreListAll(ctx context.Context, req *BaseStoreListAll) (*BaseStoreListAllResp, *rpc.CodeError) { if c.fusedErr != nil { return nil, c.fusedErr } - return rpc.UnaryClient[*PublicStoreListAllResp](c.cli.PublicStoreListAll, ctx, req) + return rpc.UnaryClient[*BaseStoreListAllResp](c.cli.BaseStoreListAll, ctx, req) } -func (s *Server) PublicStoreListAll(ctx context.Context, req *rpc.Request) (*rpc.Response, error) { - return rpc.UnaryServer(s.svrImpl.PublicStoreListAll, ctx, req) +func (s *Server) BaseStoreListAll(ctx context.Context, req *rpc.Request) (*rpc.Response, error) { + return rpc.UnaryServer(s.svrImpl.BaseStoreListAll, ctx, req) } -// 批量在指定PublicStore中创建文件夹 -type PublicStoreMkdirs struct { +// 批量在指定BaseStore中创建文件夹 +type BaseStoreMkdirs struct { UserSpace clitypes.UserSpaceDetail Pathes []string } -type PublicStoreMkdirsResp struct { +type BaseStoreMkdirsResp struct { Successes []bool } -func (c *Client) PublicStoreMkdirs(ctx context.Context, req *PublicStoreMkdirs) (*PublicStoreMkdirsResp, *rpc.CodeError) { +func (c *Client) BaseStoreMkdirs(ctx context.Context, req *BaseStoreMkdirs) (*BaseStoreMkdirsResp, *rpc.CodeError) { if c.fusedErr != nil { return nil, c.fusedErr } - return rpc.UnaryClient[*PublicStoreMkdirsResp](c.cli.PublicStoreMkdirs, ctx, req) + return rpc.UnaryClient[*BaseStoreMkdirsResp](c.cli.BaseStoreMkdirs, ctx, req) } -func (s *Server) PublicStoreMkdirs(ctx context.Context, req *rpc.Request) (*rpc.Response, error) { - return rpc.UnaryServer(s.svrImpl.PublicStoreMkdirs, ctx, req) +func (s *Server) BaseStoreMkdirs(ctx context.Context, req *rpc.Request) (*rpc.Response, error) { + return rpc.UnaryServer(s.svrImpl.BaseStoreMkdirs, ctx, req) } diff --git a/common/pkgs/storage/efile/efile.go b/common/pkgs/storage/efile/efile.go index e6754b8..7d197d2 100644 --- a/common/pkgs/storage/efile/efile.go +++ b/common/pkgs/storage/efile/efile.go @@ -32,6 +32,7 @@ type builder struct { } func (b *builder) getToken() (string, error) { + stgType := b.detail.UserSpace.Storage.(*cortypes.EFileType) cred := b.detail.UserSpace.Credential.(*cortypes.EFileCred) b.tokenLock.Lock() @@ -80,18 +81,18 @@ func (b *builder) getToken() (string, error) { } for _, d := range r.Data { - if d.ClusterID == cred.ClusterID { + if d.ClusterID == stgType.ClusterID { b.token = d.Token b.getTokenTime = time.Now() return d.Token, nil } } - return "", fmt.Errorf("clusterID %s not found", cred.ClusterID) + return "", fmt.Errorf("clusterID %s not found", stgType.ClusterID) } func (b *builder) CreateECMultiplier() (types.ECMultiplier, error) { - feat := utils.FindFeature[*cortypes.ECMultiplierFeature](b.detail.Storage) + feat := utils.FindFeature[*cortypes.ECMultiplierFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature ECMultiplier not found") } diff --git a/common/pkgs/storage/factory/factory.go b/common/pkgs/storage/factory/factory.go index 9d51ea6..b441782 100644 --- a/common/pkgs/storage/factory/factory.go +++ b/common/pkgs/storage/factory/factory.go @@ -12,7 +12,7 @@ import ( // 此函数永远不会返回nil。如果找不到对应的Builder,则会返回EmptyBuilder, // 此Builder的所有函数都会返回否定值或者封装后的ErrUnsupported错误(需要使用errors.Is检查) func GetBuilder(detail *clitypes.UserSpaceDetail) types.StorageBuilder { - typ := reflect.TypeOf(detail.Storage.Type) + typ := reflect.TypeOf(detail.UserSpace.Storage) ctor, ok := reg.StorageBuilders[typ] if !ok { diff --git a/common/pkgs/storage/factory/reg/reg.go b/common/pkgs/storage/factory/reg/reg.go index 286bd6d..87dbb91 100644 --- a/common/pkgs/storage/factory/reg/reg.go +++ b/common/pkgs/storage/factory/reg/reg.go @@ -22,7 +22,7 @@ func RegisterBuilder[T cortypes.StorageType](ctor BuilderCtor) { // 此函数永远不会返回nil。如果找不到对应的Builder,则会返回EmptyBuilder, // 此Builder的所有函数都会返回否定值或者封装后的ErrUnsupported错误(需要使用errors.Is检查) func GetBuilderInternal(detail *clitypes.UserSpaceDetail) types.StorageBuilder { - typ := reflect.TypeOf(detail.Storage.Type) + typ := reflect.TypeOf(detail.UserSpace.Storage) ctor, ok := StorageBuilders[typ] if !ok { diff --git a/common/pkgs/storage/local/local.go b/common/pkgs/storage/local/local.go index e8a4dea..bb0cfd1 100644 --- a/common/pkgs/storage/local/local.go +++ b/common/pkgs/storage/local/local.go @@ -11,7 +11,7 @@ import ( ) func init() { - reg.RegisterBuilder[*cortypes.LocalStorageType](func(detail *clitypes.UserSpaceDetail) types.StorageBuilder { + reg.RegisterBuilder[*cortypes.LocalType](func(detail *clitypes.UserSpaceDetail) types.StorageBuilder { return &builder{ detail: detail, } @@ -39,17 +39,17 @@ func (b *builder) CreateShardStore() (types.ShardStore, error) { return NewShardStore(cred.RootDir, b.detail) } -func (b *builder) CreatePublicStore() (types.PublicStore, error) { +func (b *builder) CreateBaseStore() (types.BaseStore, error) { cred, ok := b.detail.UserSpace.Credential.(*cortypes.LocalCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for local storage", b.detail.UserSpace.Credential) } - return NewPublicStore(cred.RootDir, b.detail) + return NewBaseStore(cred.RootDir, b.detail) } func (b *builder) CreateMultiparter() (types.Multiparter, error) { - feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail.Storage) + feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", cortypes.MultipartUploadFeature{}) } @@ -60,7 +60,7 @@ func (b *builder) CreateMultiparter() (types.Multiparter, error) { } func (b *builder) CreateS2STransfer() (types.S2STransfer, error) { - feat := utils.FindFeature[*cortypes.S2STransferFeature](b.detail.Storage) + feat := utils.FindFeature[*cortypes.S2STransferFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", cortypes.S2STransferFeature{}) } diff --git a/common/pkgs/storage/local/public_store.go b/common/pkgs/storage/local/public_store.go index fc4564f..9b9ab5e 100644 --- a/common/pkgs/storage/local/public_store.go +++ b/common/pkgs/storage/local/public_store.go @@ -1,51 +1,59 @@ package local import ( + "crypto/sha256" "io" "io/fs" "os" "path/filepath" "gitlink.org.cn/cloudream/common/pkgs/logger" + "gitlink.org.cn/cloudream/common/utils/io2" clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types" ) -type PublicStore struct { +type BaseStore struct { root string detail *clitypes.UserSpaceDetail } -func NewPublicStore(root string, detail *clitypes.UserSpaceDetail) (*PublicStore, error) { - return &PublicStore{ +func NewBaseStore(root string, detail *clitypes.UserSpaceDetail) (*BaseStore, error) { + return &BaseStore{ root: root, detail: detail, }, nil } -func (s *PublicStore) Write(objPath string, stream io.Reader) error { +func (s *BaseStore) Write(objPath string, stream io.Reader) (types.FileInfo, error) { absObjPath := filepath.Join(s.root, objPath) err := os.MkdirAll(filepath.Dir(absObjPath), 0755) if err != nil { - return err + return types.FileInfo{}, err } f, err := os.Create(absObjPath) if err != nil { - return err + return types.FileInfo{}, err } defer f.Close() - _, err = io.Copy(f, stream) + counter := io2.Counter(stream) + hasher := io2.NewReadHasher(sha256.New(), counter) + + _, err = io.Copy(f, hasher) if err != nil { - return err + return types.FileInfo{}, err } - return nil + return types.FileInfo{ + Hash: clitypes.NewFullHash(hasher.Sum()), + Size: counter.Count(), + }, nil } -func (s *PublicStore) Read(objPath string) (io.ReadCloser, error) { +func (s *BaseStore) Read(objPath string) (io.ReadCloser, error) { absObjPath := filepath.Join(s.root, objPath) f, err := os.Open(absObjPath) if err != nil { @@ -55,7 +63,7 @@ func (s *PublicStore) Read(objPath string) (io.ReadCloser, error) { return f, nil } -func (s *PublicStore) Mkdir(path string) error { +func (s *BaseStore) Mkdir(path string) error { absObjPath := filepath.Join(s.root, path) err := os.MkdirAll(absObjPath, 0755) if err != nil { @@ -65,10 +73,10 @@ func (s *PublicStore) Mkdir(path string) error { return nil } -func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { +func (s *BaseStore) ListAll(path string) ([]types.BaseStoreEntry, error) { absObjPath := filepath.Join(s.root, path) - var es []types.PublicStoreEntry + var es []types.BaseStoreEntry err := filepath.WalkDir(absObjPath, func(path string, d fs.DirEntry, err error) error { if err != nil { return err @@ -80,7 +88,7 @@ func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { } if d.IsDir() { - es = append(es, types.PublicStoreEntry{ + es = append(es, types.BaseStoreEntry{ Path: filepath.ToSlash(relaPath), Size: 0, IsDir: true, @@ -92,7 +100,7 @@ func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { return err } - es = append(es, types.PublicStoreEntry{ + es = append(es, types.BaseStoreEntry{ Path: filepath.ToSlash(relaPath), Size: info.Size(), IsDir: false, @@ -109,6 +117,6 @@ func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { return es, nil } -func (s *PublicStore) getLogger() logger.Logger { - return logger.WithField("PublicStore", "Local").WithField("UserSpace", s.detail.UserSpace) +func (s *BaseStore) getLogger() logger.Logger { + return logger.WithField("BaseStore", "Local").WithField("UserSpace", s.detail.UserSpace) } diff --git a/common/pkgs/storage/local/s2s.go b/common/pkgs/storage/local/s2s.go index aa866a0..d7a8384 100644 --- a/common/pkgs/storage/local/s2s.go +++ b/common/pkgs/storage/local/s2s.go @@ -21,12 +21,12 @@ type S2STransfer struct { // 只有同一个机器的存储之间才可以进行数据直传 func (s *S2STransfer) CanTransfer(src *clitypes.UserSpaceDetail) bool { - _, ok := src.Storage.Type.(*cortypes.LocalStorageType) + _, ok := src.UserSpace.Storage.(*cortypes.LocalType) if !ok { return false } - if src.Storage.MasterHub != s.detail.Storage.MasterHub { + if src.RecommendHub != s.detail.RecommendHub { return false } diff --git a/common/pkgs/storage/local/shard_store.go b/common/pkgs/storage/local/shard_store.go index 4d93f4f..c6dc1cd 100644 --- a/common/pkgs/storage/local/shard_store.go +++ b/common/pkgs/storage/local/shard_store.go @@ -14,7 +14,6 @@ import ( "gitlink.org.cn/cloudream/common/pkgs/logger" "gitlink.org.cn/cloudream/common/utils/io2" clitypes "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/storage/types" ) @@ -117,9 +116,10 @@ func (s *ShardStore) Create(stream io.Reader) (types.FileInfo, error) { counter := io2.Counter(stream) size, hash, err := s.writeTempFile(file, counter) - if stgglb.Stats.HubStorageTransfer != nil { - stgglb.Stats.HubStorageTransfer.RecordUpload(s.detail.Storage.StorageID, counter.Count(), err == nil) - } + // TODO2 + // if stgglb.Stats.HubStorageTransfer != nil { + // stgglb.Stats.HubStorageTransfer.RecordUpload(s.detail.Storage.StorageID, counter.Count(), err == nil) + // } if err != nil { // Name是文件完整路径 s.onCreateFailed(file.Name()) @@ -265,9 +265,10 @@ func (s *ShardStore) Open(opt types.OpenOption) (io.ReadCloser, error) { } return io2.CounterCloser(ret, func(cnt int64, err error) { - if stgglb.Stats.HubStorageTransfer != nil { - stgglb.Stats.HubStorageTransfer.RecordDownload(s.detail.Storage.StorageID, cnt, err == nil || err == io.EOF) - } + // TODO2 + // if stgglb.Stats.HubStorageTransfer != nil { + // stgglb.Stats.HubStorageTransfer.RecordDownload(s.detail.Storage.StorageID, cnt, err == nil || err == io.EOF) + // } }), nil } @@ -388,7 +389,7 @@ func (s *ShardStore) Stats() types.Stats { } func (s *ShardStore) getLogger() logger.Logger { - return logger.WithField("ShardStore", "Local").WithField("Storage", s.detail.Storage.String()) + return logger.WithField("ShardStore", "Local").WithField("Storage", s.detail.UserSpace.Storage.String()) } func (s *ShardStore) getFileDirFromHash(hash clitypes.FileHash) string { diff --git a/common/pkgs/storage/mashup/mashup.go b/common/pkgs/storage/mashup/mashup.go index 7304ab6..178f08f 100644 --- a/common/pkgs/storage/mashup/mashup.go +++ b/common/pkgs/storage/mashup/mashup.go @@ -1,5 +1,6 @@ package mashup +/* import ( "fmt" @@ -22,14 +23,14 @@ type builder struct { } func (b *builder) FeatureDesc() types.FeatureDesc { - stgType := b.detail.Storage.Type.(*cortypes.MashupStorageType) + stgType := b.detail.UserSpace.Storage.(*cortypes.MashupStorageType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.MashupCred) if !ok { return types.FeatureDesc{} } newDetail := *b.detail - newDetail.Storage.Type = stgType.Store + newDetail.UserSpace.Storage = stgType.Store newDetail.UserSpace.Credential = cred.Store blder := reg.GetBuilderInternal(&newDetail) @@ -37,44 +38,44 @@ func (b *builder) FeatureDesc() types.FeatureDesc { } func (b *builder) CreateShardStore() (types.ShardStore, error) { - stgType := b.detail.Storage.Type.(*cortypes.MashupStorageType) + stgType := b.detail.UserSpace.Storage.(*cortypes.MashupStorageType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.MashupCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for mashup storage", b.detail.UserSpace.Credential) } newDetail := *b.detail - newDetail.Storage.Type = stgType.Store + newDetail.UserSpace.Storage = stgType.Store newDetail.UserSpace.Credential = cred.Store blder := reg.GetBuilderInternal(&newDetail) return blder.CreateShardStore() } -func (b *builder) CreatePublicStore() (types.PublicStore, error) { - stgType := b.detail.Storage.Type.(*cortypes.MashupStorageType) +func (b *builder) CreateBaseStore() (types.BaseStore, error) { + stgType := b.detail.UserSpace.Storage.(*cortypes.MashupStorageType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.MashupCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for mashup storage", b.detail.UserSpace.Credential) } newDetail := *b.detail - newDetail.Storage.Type = stgType.Store + newDetail.UserSpace.Storage = stgType.Store newDetail.UserSpace.Credential = cred.Store blder := reg.GetBuilderInternal(&newDetail) - return blder.CreatePublicStore() + return blder.CreateBaseStore() } func (b *builder) CreateMultiparter() (types.Multiparter, error) { - stgType := b.detail.Storage.Type.(*cortypes.MashupStorageType) + stgType := b.detail.UserSpace.Storage.(*cortypes.MashupStorageType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.MashupCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for mashup storage", b.detail.UserSpace.Credential) } newDetail := *b.detail - newDetail.Storage.Type = stgType.Feature + newDetail.UserSpace.Storage = stgType.Feature newDetail.UserSpace.Credential = cred.Feature blder := reg.GetBuilderInternal(&newDetail) @@ -82,14 +83,14 @@ func (b *builder) CreateMultiparter() (types.Multiparter, error) { } func (b *builder) CreateS2STransfer() (types.S2STransfer, error) { - stgType := b.detail.Storage.Type.(*cortypes.MashupStorageType) + stgType := b.detail.UserSpace.Storage.(*cortypes.MashupStorageType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.MashupCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for mashup storage", b.detail.UserSpace.Credential) } newDetail := *b.detail - newDetail.Storage.Type = stgType.Feature + newDetail.UserSpace.Storage = stgType.Feature newDetail.UserSpace.Credential = cred.Feature blder := reg.GetBuilderInternal(&newDetail) @@ -97,16 +98,17 @@ func (b *builder) CreateS2STransfer() (types.S2STransfer, error) { } func (b *builder) CreateECMultiplier() (types.ECMultiplier, error) { - stgType := b.detail.Storage.Type.(*cortypes.MashupStorageType) + stgType := b.detail.UserSpace.Storage.(*cortypes.MashupStorageType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.MashupCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for mashup storage", b.detail.UserSpace.Credential) } newDetail := *b.detail - newDetail.Storage.Type = stgType.Feature + newDetail.UserSpace.Storage = stgType.Feature newDetail.UserSpace.Credential = cred.Feature blder := reg.GetBuilderInternal(&newDetail) return blder.CreateECMultiplier() } +*/ diff --git a/common/pkgs/storage/obs/obs.go b/common/pkgs/storage/obs/obs.go index e8f2c10..1c07070 100644 --- a/common/pkgs/storage/obs/obs.go +++ b/common/pkgs/storage/obs/obs.go @@ -40,34 +40,36 @@ func (b *builder) FeatureDesc() types.FeatureDesc { } func (b *builder) CreateShardStore() (types.ShardStore, error) { + stgType := b.detail.UserSpace.Storage.(*cortypes.OBSType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.OBSCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } - cli, bucket, err := createClient(cred) + cli, bucket, err := createClient(stgType, cred) if err != nil { return nil, err } - return NewShardStore(b.detail, cred, cli, bucket) + return NewShardStore(b.detail, stgType, cred, cli, bucket) } -func (b *builder) CreatePublicStore() (types.PublicStore, error) { +func (b *builder) CreateBaseStore() (types.BaseStore, error) { + stgType := b.detail.UserSpace.Storage.(*cortypes.OBSType) cred, ok := b.detail.UserSpace.Credential.(*cortypes.OBSCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } - cli, bucket, err := createClient(cred) + cli, bucket, err := createClient(stgType, cred) if err != nil { return nil, err } - return s3stg.NewPublicStore(b.detail, cli, bucket) + return s3stg.NewBaseStore(b.detail, cli, bucket, s3stg.BaseStoreOption{UseAWSSha256: false}) } -func createClient(cred *cortypes.OBSCred) (*s3.Client, string, error) { +func createClient(stgType *cortypes.OBSType, cred *cortypes.OBSCred) (*s3.Client, string, error) { awsConfig := aws.Config{} cre := aws.Credentials{ @@ -75,19 +77,20 @@ func createClient(cred *cortypes.OBSCred) (*s3.Client, string, error) { SecretAccessKey: cred.SK, } awsConfig.Credentials = &credentials.StaticCredentialsProvider{Value: cre} - awsConfig.Region = cred.Region + awsConfig.Region = stgType.Region options := []func(*s3.Options){} options = append(options, func(s3Opt *s3.Options) { - s3Opt.BaseEndpoint = &cred.Endpoint + s3Opt.BaseEndpoint = &stgType.Endpoint }) cli := s3.NewFromConfig(awsConfig, options...) - return cli, cred.Bucket, nil + return cli, stgType.Bucket, nil } func (b *builder) CreateMultiparter() (types.Multiparter, error) { - feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail.Storage) + stgType := b.detail.UserSpace.Storage.(*cortypes.OBSType) + feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", cortypes.MultipartUploadFeature{}) } @@ -97,7 +100,7 @@ func (b *builder) CreateMultiparter() (types.Multiparter, error) { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } - cli, bucket, err := createClient(cred) + cli, bucket, err := createClient(stgType, cred) if err != nil { return nil, err } @@ -111,7 +114,8 @@ func (b *builder) CreateMultiparter() (types.Multiparter, error) { } func (b *builder) CreateS2STransfer() (types.S2STransfer, error) { - feat := utils.FindFeature[*cortypes.S2STransferFeature](b.detail.Storage) + stgType := b.detail.UserSpace.Storage.(*cortypes.OBSType) + feat := utils.FindFeature[*cortypes.S2STransferFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", cortypes.S2STransferFeature{}) } @@ -121,5 +125,5 @@ func (b *builder) CreateS2STransfer() (types.S2STransfer, error) { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } - return NewS2STransfer(cred, feat), nil + return NewS2STransfer(stgType, cred, feat), nil } diff --git a/common/pkgs/storage/obs/obs_test.go b/common/pkgs/storage/obs/obs_test.go index 5501e7b..009d7a0 100644 --- a/common/pkgs/storage/obs/obs_test.go +++ b/common/pkgs/storage/obs/obs_test.go @@ -13,14 +13,16 @@ import ( func Test_S2S(t *testing.T) { Convey("OBS", t, func() { s2s := S2STransfer{ - cred: &cortypes.OBSCred{ + stgType: &cortypes.OBSType{ Region: "cn-north-4", Endpoint: "obs.cn-north-4.myhuaweicloud.com", - AK: "", - SK: "", Bucket: "pcm3-bucket3", ProjectID: "", }, + cred: &cortypes.OBSCred{ + AK: "", + SK: "", + }, feat: &cortypes.S2STransferFeature{ TempDir: "s2s", }, @@ -28,17 +30,16 @@ func Test_S2S(t *testing.T) { newPath, err := s2s.Transfer(context.TODO(), &clitypes.UserSpaceDetail{ UserSpace: clitypes.UserSpace{ - Credential: cortypes.OBSCred{ + Storage: &cortypes.OBSType{ Region: "cn-north-4", Endpoint: "obs.cn-north-4.myhuaweicloud.com", - AK: "", - SK: "", Bucket: "pcm2-bucket2", ProjectID: "", }, - }, - Storage: cortypes.Storage{ - Type: &cortypes.OBSType{}, + Credential: cortypes.OBSCred{ + AK: "", + SK: "", + }, }, }, "test_data/test03.txt", types.S2SOption{}) defer s2s.Abort() diff --git a/common/pkgs/storage/obs/s2s.go b/common/pkgs/storage/obs/s2s.go index f0a46d9..9c889a4 100644 --- a/common/pkgs/storage/obs/s2s.go +++ b/common/pkgs/storage/obs/s2s.go @@ -18,16 +18,18 @@ import ( ) type S2STransfer struct { - cred *cortypes.OBSCred - feat *cortypes.S2STransferFeature - taskID *int64 - omsCli *oms.OmsClient + stgType *cortypes.OBSType + cred *cortypes.OBSCred + feat *cortypes.S2STransferFeature + taskID *int64 + omsCli *oms.OmsClient } -func NewS2STransfer(cred *cortypes.OBSCred, feat *cortypes.S2STransferFeature) *S2STransfer { +func NewS2STransfer(stgType *cortypes.OBSType, cred *cortypes.OBSCred, feat *cortypes.S2STransferFeature) *S2STransfer { return &S2STransfer{ - cred: cred, - feat: feat, + stgType: stgType, + cred: cred, + feat: feat, } } @@ -41,19 +43,19 @@ func (s *S2STransfer) CanTransfer(src *clitypes.UserSpaceDetail) bool { func (s *S2STransfer) Transfer(ctx context.Context, src *clitypes.UserSpaceDetail, srcPath string, opt types.S2SOption) (string, error) { req := s.makeRequest(src, srcPath) if req == nil { - return "", fmt.Errorf("unsupported source storage type: %T", src.Storage.Type) + return "", fmt.Errorf("unsupported source storage type: %T", src.UserSpace.Storage) } auth, err := basic.NewCredentialsBuilder(). WithAk(s.cred.AK). WithSk(s.cred.SK). - WithProjectId(s.cred.ProjectID). + WithProjectId(s.stgType.ProjectID). SafeBuild() if err != nil { return "", err } - region, err := omsregion.SafeValueOf(s.cred.Region) + region, err := omsregion.SafeValueOf(s.stgType.Region) if err != nil { return "", err } @@ -75,10 +77,10 @@ func (s *S2STransfer) Transfer(ctx context.Context, src *clitypes.UserSpaceDetai TaskType: &taskType, SrcNode: req, DstNode: &model.DstNodeReq{ - Region: s.cred.Region, + Region: s.stgType.Region, Ak: s.cred.AK, Sk: s.cred.SK, - Bucket: s.cred.Bucket, + Bucket: s.stgType.Bucket, SavePrefix: &tempPrefix, }, }, @@ -98,7 +100,7 @@ func (s *S2STransfer) Transfer(ctx context.Context, src *clitypes.UserSpaceDetai } func (s *S2STransfer) makeRequest(srcStg *clitypes.UserSpaceDetail, srcPath string) *model.SrcNodeReq { - switch srcStg.Storage.Type.(type) { + switch srcType := srcStg.UserSpace.Storage.(type) { case *cortypes.OBSType: cloudType := "HuaweiCloud" @@ -109,10 +111,10 @@ func (s *S2STransfer) makeRequest(srcStg *clitypes.UserSpaceDetail, srcPath stri return &model.SrcNodeReq{ CloudType: &cloudType, - Region: &cred.Region, + Region: &srcType.Region, Ak: &cred.AK, Sk: &cred.SK, - Bucket: &cred.Bucket, + Bucket: &srcType.Bucket, ObjectKey: &[]string{srcPath}, } diff --git a/common/pkgs/storage/obs/shard_store.go b/common/pkgs/storage/obs/shard_store.go index dd6e13b..cf30f29 100644 --- a/common/pkgs/storage/obs/shard_store.go +++ b/common/pkgs/storage/obs/shard_store.go @@ -11,12 +11,14 @@ import ( type ShardStore struct { *s3.ShardStore - cred *cortypes.OBSCred + stgType *cortypes.OBSType + cred *cortypes.OBSCred } -func NewShardStore(detail *clitypes.UserSpaceDetail, cred *cortypes.OBSCred, s3Cli *awss3.Client, bkt string) (*ShardStore, error) { +func NewShardStore(detail *clitypes.UserSpaceDetail, stgType *cortypes.OBSType, cred *cortypes.OBSCred, s3Cli *awss3.Client, bkt string) (*ShardStore, error) { sd := ShardStore{ - cred: cred, + stgType: stgType, + cred: cred, } var err error @@ -31,7 +33,7 @@ func NewShardStore(detail *clitypes.UserSpaceDetail, cred *cortypes.OBSCred, s3C } func (s *ShardStore) HTTPBypassRead(fileHash clitypes.FileHash) (types.HTTPRequest, error) { - cli, err := obs.New(s.cred.AK, s.cred.SK, s.cred.Endpoint) + cli, err := obs.New(s.cred.AK, s.cred.SK, s.stgType.Endpoint) if err != nil { return types.HTTPRequest{}, err } diff --git a/common/pkgs/storage/pool/pool.go b/common/pkgs/storage/pool/pool.go index cedacb4..c81fa27 100644 --- a/common/pkgs/storage/pool/pool.go +++ b/common/pkgs/storage/pool/pool.go @@ -75,8 +75,8 @@ func (p *Pool) GetShardStore(spaceDetail *clitypes.UserSpaceDetail) (types.Shard return space.store, nil } -func (p *Pool) GetPublicStore(spaceDetail *clitypes.UserSpaceDetail) (types.PublicStore, error) { - return factory.GetBuilder(spaceDetail).CreatePublicStore() +func (p *Pool) GetBaseStore(spaceDetail *clitypes.UserSpaceDetail) (types.BaseStore, error) { + return factory.GetBuilder(spaceDetail).CreateBaseStore() } func (p *Pool) GetMultiparter(spaceDetail *clitypes.UserSpaceDetail) (types.Multiparter, error) { diff --git a/common/pkgs/storage/s3/public_store.go b/common/pkgs/storage/s3/public_store.go index 846cfd0..9ca5d16 100644 --- a/common/pkgs/storage/s3/public_store.go +++ b/common/pkgs/storage/s3/public_store.go @@ -3,42 +3,87 @@ package s3 import ( "bytes" "context" + "crypto/sha256" + "errors" + "fmt" "io" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/s3" + s3types "github.com/aws/aws-sdk-go-v2/service/s3/types" "gitlink.org.cn/cloudream/common/pkgs/logger" + "gitlink.org.cn/cloudream/common/utils/io2" clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types" ) -type PublicStore struct { +type BaseStore struct { Detail *clitypes.UserSpaceDetail Bucket string cli *s3.Client + opt BaseStoreOption } -func NewPublicStore(detail *clitypes.UserSpaceDetail, cli *s3.Client, bkt string) (*PublicStore, error) { - return &PublicStore{ +type BaseStoreOption struct { + UseAWSSha256 bool // 能否直接使用AWS提供的SHA256校验,如果不行,则使用本地计算。默认使用本地计算。 +} + +func NewBaseStore(detail *clitypes.UserSpaceDetail, cli *s3.Client, bkt string, opt BaseStoreOption) (*BaseStore, error) { + return &BaseStore{ Detail: detail, Bucket: bkt, cli: cli, + opt: opt, }, nil } -func (s *PublicStore) Write(objPath string, stream io.Reader) error { +func (s *BaseStore) Write(objPath string, stream io.Reader) (types.FileInfo, error) { key := objPath + counter := io2.Counter(stream) + + if s.opt.UseAWSSha256 { + resp, err := s.cli.PutObject(context.TODO(), &s3.PutObjectInput{ + Bucket: aws.String(s.Bucket), + Key: aws.String(key), + Body: counter, + ChecksumAlgorithm: s3types.ChecksumAlgorithmSha256, + }) + if err != nil { + return types.FileInfo{}, err + } + if resp.ChecksumSHA256 == nil { + return types.FileInfo{}, errors.New("SHA256 checksum not found in response") + } + + hash, err := DecodeBase64Hash(*resp.ChecksumSHA256) + if err != nil { + return types.FileInfo{}, fmt.Errorf("decode SHA256 checksum: %v", err) + } + + return types.FileInfo{ + Hash: clitypes.NewFullHash(hash), + Size: counter.Count(), + }, nil + } + + hashStr := io2.NewReadHasher(sha256.New(), counter) _, err := s.cli.PutObject(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(s.Bucket), Key: aws.String(key), - Body: stream, + Body: counter, }) + if err != nil { + return types.FileInfo{}, err + } - return err + return types.FileInfo{ + Hash: clitypes.NewFullHash(hashStr.Sum()), + Size: counter.Count(), + }, nil } -func (s *PublicStore) Read(objPath string) (io.ReadCloser, error) { +func (s *BaseStore) Read(objPath string) (io.ReadCloser, error) { key := objPath resp, err := s.cli.GetObject(context.TODO(), &s3.GetObjectInput{ @@ -53,7 +98,7 @@ func (s *PublicStore) Read(objPath string) (io.ReadCloser, error) { return resp.Body, nil } -func (s *PublicStore) Mkdir(path string) error { +func (s *BaseStore) Mkdir(path string) error { _, err := s.cli.PutObject(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(s.Bucket), Key: aws.String(path + "/"), @@ -62,7 +107,7 @@ func (s *PublicStore) Mkdir(path string) error { return err } -func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { +func (s *BaseStore) ListAll(path string) ([]types.BaseStoreEntry, error) { key := path // TODO 待测试 @@ -72,7 +117,7 @@ func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { Delimiter: aws.String("/"), } - var objs []types.PublicStoreEntry + var objs []types.BaseStoreEntry var marker *string for { @@ -83,7 +128,7 @@ func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { } for _, obj := range resp.Contents { - objs = append(objs, types.PublicStoreEntry{ + objs = append(objs, types.BaseStoreEntry{ Path: *obj.Key, Size: *obj.Size, IsDir: false, @@ -100,13 +145,13 @@ func (s *PublicStore) ListAll(path string) ([]types.PublicStoreEntry, error) { return objs, nil } -func (s *PublicStore) getLogger() logger.Logger { - return logger.WithField("PublicStore", "S3").WithField("Storage", s.Detail.Storage.String()) +func (s *BaseStore) getLogger() logger.Logger { + return logger.WithField("BaseStore", "S3").WithField("Storage", s.Detail.UserSpace.Storage.String()) } -var _ types.BypassPublicRead = (*PublicStore)(nil) +var _ types.BypassPublicRead = (*BaseStore)(nil) -func (s *PublicStore) BypassPublicRead(pa string) (types.BypassFilePath, error) { +func (s *BaseStore) BypassPublicRead(pa string) (types.BypassFilePath, error) { info, err := s.cli.HeadObject(context.TODO(), &s3.HeadObjectInput{ Bucket: aws.String(s.Bucket), Key: aws.String(pa), @@ -125,9 +170,9 @@ func (s *PublicStore) BypassPublicRead(pa string) (types.BypassFilePath, error) }, nil } -var _ types.BypassPublicWrite = (*PublicStore)(nil) +var _ types.BypassPublicWrite = (*BaseStore)(nil) -func (s *PublicStore) BypassedPublic(info types.BypassedFileInfo, dstPath string) error { +func (s *BaseStore) BypassedPublic(info types.BypassedFileInfo, dstPath string) error { _, err := s.cli.CopyObject(context.TODO(), &s3.CopyObjectInput{ Bucket: aws.String(s.Bucket), CopySource: aws.String(s.Bucket + "/" + info.Path), diff --git a/common/pkgs/storage/s3/s3.go b/common/pkgs/storage/s3/s3.go index c586724..be06a8f 100644 --- a/common/pkgs/storage/s3/s3.go +++ b/common/pkgs/storage/s3/s3.go @@ -39,12 +39,13 @@ func (b *builder) FeatureDesc() types.FeatureDesc { } func (b *builder) CreateShardStore() (types.ShardStore, error) { + stgType := b.detail.UserSpace.Storage.(*cortypes.S3Type) s3Cred, ok := b.detail.UserSpace.Credential.(*cortypes.S3Cred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for s3 storage", b.detail.UserSpace.Credential) } - cli, bkt, err := createClient(s3Cred) + cli, bkt, err := createClient(stgType, s3Cred) if err != nil { return nil, err } @@ -52,21 +53,21 @@ func (b *builder) CreateShardStore() (types.ShardStore, error) { return NewShardStore(b.detail, cli, bkt, ShardStoreOption{UseAWSSha256: true}) } -func (b *builder) CreatePublicStore() (types.PublicStore, error) { +func (b *builder) CreateBaseStore() (types.BaseStore, error) { + stgType := b.detail.UserSpace.Storage.(*cortypes.S3Type) s3Cred, ok := b.detail.UserSpace.Credential.(*cortypes.S3Cred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for s3 storage", b.detail.UserSpace.Credential) } - - cli, bkt, err := createClient(s3Cred) + cli, bkt, err := createClient(stgType, s3Cred) if err != nil { return nil, err } - return NewPublicStore(b.detail, cli, bkt) + return NewBaseStore(b.detail, cli, bkt, BaseStoreOption{UseAWSSha256: false}) } -func createClient(cred *cortypes.S3Cred) (*s3.Client, string, error) { +func createClient(stgType *cortypes.S3Type, cred *cortypes.S3Cred) (*s3.Client, string, error) { awsConfig := aws.Config{} if cred.AK != "" && cred.SK != "" { @@ -77,29 +78,30 @@ func createClient(cred *cortypes.S3Cred) (*s3.Client, string, error) { awsConfig.Credentials = &credentials.StaticCredentialsProvider{Value: cre} } - awsConfig.Region = cred.Region + awsConfig.Region = stgType.Region options := []func(*s3.Options){} options = append(options, func(s3Opt *s3.Options) { - s3Opt.BaseEndpoint = &cred.Endpoint + s3Opt.BaseEndpoint = &stgType.Endpoint }) cli := s3.NewFromConfig(awsConfig, options...) - return cli, cred.Bucket, nil + return cli, stgType.Bucket, nil } func (b *builder) CreateMultiparter() (types.Multiparter, error) { - feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail.Storage) + stgType := b.detail.UserSpace.Storage.(*cortypes.S3Type) + feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", cortypes.MultipartUploadFeature{}) } s3Cred, ok := b.detail.UserSpace.Credential.(*cortypes.S3Cred) if !ok { - return nil, fmt.Errorf("invalid storage credential type %T for s3 public store", b.detail.UserSpace.Credential) + return nil, fmt.Errorf("invalid storage credential type %T for s3 base store", b.detail.UserSpace.Credential) } - cli, bucket, err := createClient(s3Cred) + cli, bucket, err := createClient(stgType, s3Cred) if err != nil { return nil, err } diff --git a/common/pkgs/storage/s3/shard_store.go b/common/pkgs/storage/s3/shard_store.go index 294cad2..5ed5152 100644 --- a/common/pkgs/storage/s3/shard_store.go +++ b/common/pkgs/storage/s3/shard_store.go @@ -17,7 +17,6 @@ import ( "gitlink.org.cn/cloudream/common/utils/io2" "gitlink.org.cn/cloudream/common/utils/os2" clitypes "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/storage/types" ) @@ -161,9 +160,10 @@ func (s *ShardStore) createWithAwsSha256(stream io.Reader) (types.FileInfo, erro Body: counter, ChecksumAlgorithm: s3types.ChecksumAlgorithmSha256, }) - if stgglb.Stats.HubStorageTransfer != nil { - stgglb.Stats.HubStorageTransfer.RecordUpload(s.Detail.Storage.StorageID, counter.Count(), err == nil) - } + // TODO2 + // if stgglb.Stats.HubStorageTransfer != nil { + // stgglb.Stats.HubStorageTransfer.RecordUpload(s.Detail.Storage.StorageID, counter.Count(), err == nil) + // } if err != nil { log.Warnf("uploading file %v: %v", key, err) @@ -203,9 +203,10 @@ func (s *ShardStore) createWithCalcSha256(stream io.Reader) (types.FileInfo, err Key: aws.String(key), Body: counter, }) - if stgglb.Stats.HubStorageTransfer != nil { - stgglb.Stats.HubStorageTransfer.RecordUpload(s.Detail.Storage.StorageID, counter.Count(), err == nil) - } + // TODO2 + // if stgglb.Stats.HubStorageTransfer != nil { + // stgglb.Stats.HubStorageTransfer.RecordUpload(s.Detail.Storage.StorageID, counter.Count(), err == nil) + // } if err != nil { log.Warnf("uploading file %v: %v", key, err) @@ -302,9 +303,10 @@ func (s *ShardStore) Open(opt types.OpenOption) (io.ReadCloser, error) { } return io2.CounterCloser(resp.Body, func(cnt int64, err error) { - if stgglb.Stats.HubStorageTransfer != nil { - stgglb.Stats.HubStorageTransfer.RecordDownload(s.Detail.Storage.StorageID, cnt, err == nil || err == io.EOF) - } + // TODO2 + // if stgglb.Stats.HubStorageTransfer != nil { + // stgglb.Stats.HubStorageTransfer.RecordDownload(s.Detail.Storage.StorageID, cnt, err == nil || err == io.EOF) + // } }), nil } diff --git a/common/pkgs/storage/types/bypass.go b/common/pkgs/storage/types/bypass.go index eaa35ed..92ab38a 100644 --- a/common/pkgs/storage/types/bypass.go +++ b/common/pkgs/storage/types/bypass.go @@ -16,7 +16,7 @@ type BypassShardWrite interface { BypassedShard(info BypassedFileInfo) error } -// 不通过PublicStore上传文件。 +// 不通过BaseStore上传文件。 type BypassPublicWrite interface { BypassedPublic(info BypassedFileInfo, dstPath string) error } @@ -33,7 +33,7 @@ type BypassShardRead interface { BypassShardRead(fileHash clitypes.FileHash) (BypassFilePath, error) } -// 不通过PublicStore读取文件。虽然仅使用path就已经可以读取到文件,但还是增加了此接口用于获取更详细的文件信息。 +// 不通过BaseStore读取文件。虽然仅使用path就已经可以读取到文件,但还是增加了此接口用于获取更详细的文件信息。 type BypassPublicRead interface { BypassPublicRead(path string) (BypassFilePath, error) } diff --git a/common/pkgs/storage/types/empty_builder.go b/common/pkgs/storage/types/empty_builder.go index 105cdf9..25666b7 100644 --- a/common/pkgs/storage/types/empty_builder.go +++ b/common/pkgs/storage/types/empty_builder.go @@ -14,21 +14,21 @@ func (b *EmptyBuilder) FeatureDesc() FeatureDesc { return FeatureDesc{} } func (b *EmptyBuilder) CreateShardStore() (ShardStore, error) { - return nil, fmt.Errorf("create shard store for %T: %w", b.Detail.Storage.Type, ErrUnsupported) + return nil, fmt.Errorf("create shard store for %T: %w", b.Detail.UserSpace.Storage, ErrUnsupported) } -func (b *EmptyBuilder) CreatePublicStore() (PublicStore, error) { - return nil, fmt.Errorf("create public store for %T: %w", b.Detail.Storage.Type, ErrUnsupported) +func (b *EmptyBuilder) CreateBaseStore() (BaseStore, error) { + return nil, fmt.Errorf("create base store for %T: %w", b.Detail.UserSpace.Storage, ErrUnsupported) } func (b *EmptyBuilder) CreateMultiparter() (Multiparter, error) { - return nil, fmt.Errorf("create multipart initiator for %T: %w", b.Detail.Storage.Type, ErrUnsupported) + return nil, fmt.Errorf("create multipart initiator for %T: %w", b.Detail.UserSpace.Storage, ErrUnsupported) } func (b *EmptyBuilder) CreateS2STransfer() (S2STransfer, error) { - return nil, fmt.Errorf("create s2s transfer for %T: %w", b.Detail.Storage.Type, ErrUnsupported) + return nil, fmt.Errorf("create s2s transfer for %T: %w", b.Detail.UserSpace.Storage, ErrUnsupported) } func (b *EmptyBuilder) CreateECMultiplier() (ECMultiplier, error) { - return nil, fmt.Errorf("create ec multiplier for %T: %w", b.Detail.Storage.Type, ErrUnsupported) + return nil, fmt.Errorf("create ec multiplier for %T: %w", b.Detail.UserSpace.Storage, ErrUnsupported) } diff --git a/common/pkgs/storage/types/public_store.go b/common/pkgs/storage/types/public_store.go index 45ada8d..96c08d2 100644 --- a/common/pkgs/storage/types/public_store.go +++ b/common/pkgs/storage/types/public_store.go @@ -4,19 +4,19 @@ import ( "io" ) -type PublicStoreEntry struct { +type BaseStoreEntry struct { Path string Size int64 IsDir bool } -type PublicStore interface { - Write(path string, stream io.Reader) error +type BaseStore interface { + Write(path string, stream io.Reader) (FileInfo, error) Read(path string) (io.ReadCloser, error) // 创建指定路径的文件夹。对于不支持空文件夹的存储系统来说,可以采用创建以/结尾的对象的方式来模拟文件夹。 Mkdir(path string) error // 返回指定路径下的所有文件,文件路径是包含path在内的完整路径。返回结果的第一条一定是路径本身,可能是文件,也可能是目录。 // 如果路径不存在,那么不会返回错误,而是返回一个空列表。 // 返回的内容严格按照存储系统的原始结果来,比如当存储系统是一个对象存储时,那么就可能不会包含目录,或者包含用于模拟的以“/”结尾的对象。 - ListAll(path string) ([]PublicStoreEntry, error) + ListAll(path string) ([]BaseStoreEntry, error) } diff --git a/common/pkgs/storage/types/types.go b/common/pkgs/storage/types/types.go index a99de66..c3bc005 100644 --- a/common/pkgs/storage/types/types.go +++ b/common/pkgs/storage/types/types.go @@ -20,10 +20,10 @@ type StorageEventChan = async.UnboundChannel[StorageEvent] type StorageBuilder interface { // 关于此存储系统特性功能的描述 FeatureDesc() FeatureDesc + // 创建一个提供基础读写存储服务能力的组件 + CreateBaseStore() (BaseStore, error) // 创建一个分片存储组件 CreateShardStore() (ShardStore, error) - // 创建一个公共存储组件 - CreatePublicStore() (PublicStore, error) // 创建一个分片上传组件 CreateMultiparter() (Multiparter, error) // 创建一个存储服务直传组件 diff --git a/common/pkgs/storage/utils/utils.go b/common/pkgs/storage/utils/utils.go index 2fb3fa0..4614a27 100644 --- a/common/pkgs/storage/utils/utils.go +++ b/common/pkgs/storage/utils/utils.go @@ -1,11 +1,12 @@ package utils import ( + clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types" cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" ) -func FindFeature[T cortypes.StorageFeature](detail cortypes.Storage) T { - for _, f := range detail.Features { +func FindFeature[T cortypes.StorageFeature](detail *clitypes.UserSpaceDetail) T { + for _, f := range detail.UserSpace.Features { f2, ok := f.(T) if ok { return f2 diff --git a/coordinator/internal/cmd/migrate.go b/coordinator/internal/cmd/migrate.go index 7c21527..887dbc9 100644 --- a/coordinator/internal/cmd/migrate.go +++ b/coordinator/internal/cmd/migrate.go @@ -40,8 +40,7 @@ func migrate(configPath string) { migrateOne(db, cortypes.HubConnectivity{}) migrateOne(db, cortypes.Hub{}) - migrateOne(db, cortypes.Location{}) - migrateOne(db, cortypes.Storage{}) + migrateOne(db, cortypes.HubLocation{}) migrateOne(db, cortypes.User{}) fmt.Println("migrate success") diff --git a/coordinator/internal/db/hub_location.go b/coordinator/internal/db/hub_location.go new file mode 100644 index 0000000..3a90e26 --- /dev/null +++ b/coordinator/internal/db/hub_location.go @@ -0,0 +1,25 @@ +package db + +import ( + cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" +) + +type HubLocationDB struct { + *DB +} + +func (db *DB) HubLocation() *HubLocationDB { + return &HubLocationDB{DB: db} +} + +func (*HubLocationDB) GetByHubID(ctx SQLContext, id cortypes.HubID) ([]cortypes.HubLocation, error) { + var ret []cortypes.HubLocation + err := ctx.Where("HubID = ?", id).Find(&ret).Error + return ret, err +} + +func (*HubLocationDB) GetAll(ctx SQLContext) ([]cortypes.HubLocation, error) { + var ret []cortypes.HubLocation + err := ctx.Find(&ret).Error + return ret, err +} diff --git a/coordinator/internal/db/location.go b/coordinator/internal/db/location.go deleted file mode 100644 index 38c0af8..0000000 --- a/coordinator/internal/db/location.go +++ /dev/null @@ -1,36 +0,0 @@ -package db - -import ( - "fmt" - - cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" -) - -type LocationDB struct { - *DB -} - -func (db *DB) Location() *LocationDB { - return &LocationDB{DB: db} -} - -func (*LocationDB) GetByID(ctx SQLContext, id int64) (cortypes.Location, error) { - var ret cortypes.Location - err := ctx.First(&ret, id).Error - return ret, err -} - -func (db *LocationDB) FindLocationByExternalIP(ctx SQLContext, ip string) (cortypes.Location, error) { - var locID int64 - err := ctx.Table("Hub").Select("LocationID").Where("ExternalIP = ?", ip).Scan(&locID).Error - if err != nil { - return cortypes.Location{}, fmt.Errorf("finding hub by external ip: %w", err) - } - - loc, err := db.GetByID(ctx, locID) - if err != nil { - return cortypes.Location{}, fmt.Errorf("getting location by id: %w", err) - } - - return loc, nil -} diff --git a/coordinator/internal/db/storage.go b/coordinator/internal/db/storage.go deleted file mode 100644 index 1d3a0d7..0000000 --- a/coordinator/internal/db/storage.go +++ /dev/null @@ -1,43 +0,0 @@ -package db - -import ( - cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" -) - -type StorageDB struct { - *DB -} - -func (db *DB) Storage() *StorageDB { - return &StorageDB{DB: db} -} - -func (db *StorageDB) GetByID(ctx SQLContext, stgID cortypes.StorageID) (cortypes.Storage, error) { - var stg cortypes.Storage - err := ctx.Table("Storage").First(&stg, stgID).Error - return stg, err -} - -func (StorageDB) GetAllIDs(ctx SQLContext) ([]cortypes.StorageID, error) { - var stgs []cortypes.StorageID - err := ctx.Table("Storage").Select("StorageID").Find(&stgs).Error - return stgs, err -} - -func (db *StorageDB) BatchGetByID(ctx SQLContext, stgIDs []cortypes.StorageID) ([]cortypes.Storage, error) { - var stgs []cortypes.Storage - err := ctx.Table("Storage").Find(&stgs, "StorageID IN (?)", stgIDs).Error - return stgs, err -} - -func (db *StorageDB) BatchGetAllStorageIDs(ctx SQLContext, start int, count int) ([]cortypes.StorageID, error) { - var ret []cortypes.StorageID - err := ctx.Table("Storage").Select("StorageID").Find(&ret).Limit(count).Offset(start).Error - return ret, err -} - -func (db *StorageDB) GetHubStorages(ctx SQLContext, hubID cortypes.HubID) ([]cortypes.Storage, error) { - var stgs []cortypes.Storage - err := ctx.Table("Storage").Select("Storage.*").Find(&stgs, "MasterHub = ?", hubID).Error - return stgs, err -} diff --git a/coordinator/internal/rpc/storage.go b/coordinator/internal/rpc/storage.go index 9aa6c79..9a230f6 100644 --- a/coordinator/internal/rpc/storage.go +++ b/coordinator/internal/rpc/storage.go @@ -2,40 +2,43 @@ package rpc import ( "context" - "fmt" "gitlink.org.cn/cloudream/common/consts/errorcode" "gitlink.org.cn/cloudream/common/pkgs/logger" - "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc" corrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/coordinator" "gitlink.org.cn/cloudream/jcs-pub/coordinator/internal/db" cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" ) -func (svc *Service) GetStorageDetails(ctx context.Context, msg *corrpc.GetStorageDetails) (*corrpc.GetStorageDetailsResp, *rpc.CodeError) { +func (svc *Service) SelectStorageHub(ctx context.Context, msg *corrpc.SelectStorageHub) (*corrpc.SelectStorageHubResp, *rpc.CodeError) { d := svc.db - stgs, err := db.DoTx02(d, func(tx db.SQLContext) ([]*cortypes.StorageDetail, error) { - stgs, err := d.Storage().BatchGetByID(tx, msg.StorageIDs) + resp, err := db.DoTx02(d, func(tx db.SQLContext) ([]*cortypes.Hub, error) { + allLoc, err := d.HubLocation().GetAll(tx) if err != nil { - return nil, fmt.Errorf("getting storages: %v", err) - } - stgMap := make(map[cortypes.StorageID]*cortypes.Storage) - for _, stg := range stgs { - s := stg - stgMap[stg.StorageID] = &s + return nil, err } - hubIDs := make([]cortypes.HubID, 0, len(stgs)) - for _, stg := range stgs { - if stg.MasterHub != 0 { - hubIDs = append(hubIDs, stg.MasterHub) + stgHubIDs := make([]cortypes.HubID, 0, len(msg.Storages)) + for _, stg := range msg.Storages { + stgLoc := stg.GetLocation() + + var matchedHubID cortypes.HubID + var matchedScore int + for _, loc := range allLoc { + sc := matchLocation(stgLoc, loc) + if sc > matchedScore { + matchedScore = sc + matchedHubID = loc.HubID + } } + + stgHubIDs = append(stgHubIDs, matchedHubID) } - hubs, err := d.Hub().BatchGetByID(tx, hubIDs) + hubs, err := d.Hub().BatchGetByID(tx, stgHubIDs) if err != nil { - return nil, fmt.Errorf("getting hubs: %v", err) + return nil, err } hubMap := make(map[cortypes.HubID]*cortypes.Hub) @@ -44,24 +47,43 @@ func (svc *Service) GetStorageDetails(ctx context.Context, msg *corrpc.GetStorag hubMap[hub.HubID] = &h } - details := make([]*cortypes.StorageDetail, len(msg.StorageIDs)) - for i, stgID := range msg.StorageIDs { - stg := stgMap[stgID] - if stg == nil { - continue - } - details[i] = &cortypes.StorageDetail{ - Storage: *stg, - MasterHub: hubMap[stg.MasterHub], - } + resp := make([]*cortypes.Hub, len(msg.Storages)) + for i := range msg.Storages { + resp[i] = hubMap[stgHubIDs[i]] } - - return details, nil + return resp, nil }) + if err != nil { - logger.Warnf("getting storage details: %s", err.Error()) - return nil, rpc.Failed(errorcode.OperationFailed, fmt.Sprintf("getting storage details: %v", err)) + logger.Warnf("select storage hubs: %s", err.Error()) + return nil, rpc.Failed(errorcode.OperationFailed, "%v", err) + } + + return &corrpc.SelectStorageHubResp{ + Hubs: resp, + }, nil +} + +// 匹配规则: +// 1. 按照StorageName、Location顺序检查StorageLocation和HubLocation +// 2. "*"代表通配符,匹配任意值,如果匹配到了通配,那么就直接结束匹配 +// 3. 匹配越精确,分数越高 +func matchLocation(loc cortypes.Location, hubLoc cortypes.HubLocation) int { + if hubLoc.StorageName == "*" { + return 1 + } + + if hubLoc.StorageName != loc.StorageName { + return 0 + } + + if hubLoc.Location == "*" { + return 2 + } + + if hubLoc.Location == loc.Location { + return 3 } - return corrpc.RespGetStorageDetails(stgs), nil + return 0 } diff --git a/coordinator/types/location.go b/coordinator/types/location.go new file mode 100644 index 0000000..2ef2ccb --- /dev/null +++ b/coordinator/types/location.go @@ -0,0 +1,6 @@ +package types + +type Location struct { + StorageName string `json:"storageName"` + Location string `json:"location"` +} diff --git a/coordinator/types/storage.go b/coordinator/types/storage.go index 5a4da27..02b078d 100644 --- a/coordinator/types/storage.go +++ b/coordinator/types/storage.go @@ -1,12 +1,11 @@ package types import ( - "fmt" - "gitlink.org.cn/cloudream/common/pkgs/types" "gitlink.org.cn/cloudream/common/utils/serder" ) +/* type Storage struct { StorageID StorageID `json:"storageID" gorm:"column:StorageID; primaryKey; type:bigint; autoIncrement;"` Name string `json:"name" gorm:"column:Name; type:varchar(256); not null"` @@ -30,17 +29,20 @@ type StorageDetail struct { Storage Storage MasterHub *Hub } - +*/ // 存储服务地址 type StorageType interface { GetStorageType() string + GetLocation() Location + // 判断两个存储服务是否是同一个。注意要精细比较,不仅是需要类型相同,甚至需要是同一个桶。 + Equals(other StorageType) bool // 输出调试用的字符串,不要包含敏感信息 String() string } var _ = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[StorageType]( - (*MashupStorageType)(nil), - (*LocalStorageType)(nil), + // (*MashupStorageType)(nil), + (*LocalType)(nil), (*OBSType)(nil), (*OSSType)(nil), (*COSType)(nil), @@ -48,44 +50,75 @@ var _ = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[Storage (*S3Type)(nil), )), "type") -// 多种存储服务的混合存储服务。需谨慎选择存储服务的组合,避免出Bug -type MashupStorageType struct { - serder.Metadata `union:"Mashup"` - Type string `json:"type"` - Store StorageType `json:"store"` // 创建ShardStore或PublicStore时,使用的存储服务类型 - Feature StorageType `json:"feature"` // 根据Feature创建组件时使用的存储服务类型 -} +// // 多种存储服务的混合存储服务。需谨慎选择存储服务的组合,避免出Bug +// type MashupStorageType struct { +// serder.Metadata `union:"Mashup"` +// Type string `json:"type"` +// Store StorageType `json:"store"` // 创建ShardStore或BaseStore时,使用的存储服务类型 +// Feature StorageType `json:"feature"` // 根据Feature创建组件时使用的存储服务类型 +// } -func (a *MashupStorageType) GetStorageType() string { - return "Mashup" -} +// func (a *MashupStorageType) GetStorageType() string { +// return "Mashup" +// } -func (a *MashupStorageType) String() string { - return "Mashup" -} +// func (a *MashupStorageType) String() string { +// return "Mashup" +// } -type LocalStorageType struct { +type LocalType struct { serder.Metadata `union:"Local"` - Type string `json:"type"` + Type string `json:"type"` + Location Location `json:"location"` } -func (a *LocalStorageType) GetStorageType() string { +func (a *LocalType) GetStorageType() string { return "Local" } -func (a *LocalStorageType) String() string { +func (a *LocalType) GetLocation() Location { + return a.Location +} + +func (a *LocalType) Equals(other StorageType) bool { + o, ok := other.(*LocalType) + if !ok { + return false + } + return a.Location == o.Location +} + +func (a *LocalType) String() string { return "Local" } type OSSType struct { serder.Metadata `union:"OSS"` Type string `json:"type"` + Region string `json:"region"` + Endpoint string `json:"endpoint"` + Bucket string `json:"bucket"` } func (a *OSSType) GetStorageType() string { return "OSS" } +func (a *OSSType) GetLocation() Location { + return Location{ + StorageName: a.GetStorageType(), + Location: a.Region, + } +} + +func (a *OSSType) Equals(other StorageType) bool { + o, ok := other.(*OSSType) + if !ok { + return false + } + return a.Region == o.Region && a.Endpoint == o.Endpoint && a.Bucket == o.Bucket +} + func (a *OSSType) String() string { return "OSS" } @@ -93,12 +126,31 @@ func (a *OSSType) String() string { type OBSType struct { serder.Metadata `union:"OBS"` Type string `json:"type"` + Region string `json:"region"` + Endpoint string `json:"endpoint"` + Bucket string `json:"bucket"` + ProjectID string `json:"projectID"` } func (a *OBSType) GetStorageType() string { return "OBS" } +func (a *OBSType) GetLocation() Location { + return Location{ + StorageName: a.GetStorageType(), + Location: a.Region, + } +} + +func (a *OBSType) Equals(other StorageType) bool { + o, ok := other.(*OBSType) + if !ok { + return false + } + return a.Region == o.Region && a.Endpoint == o.Endpoint && a.Bucket == o.Bucket && a.ProjectID == o.ProjectID +} + func (a *OBSType) String() string { return "OBS" } @@ -106,12 +158,30 @@ func (a *OBSType) String() string { type COSType struct { serder.Metadata `union:"COS"` Type string `json:"type"` + Region string `json:"region"` + Endpoint string `json:"endpoint"` + Bucket string `json:"bucket"` } func (a *COSType) GetStorageType() string { return "COS" } +func (a *COSType) GetLocation() Location { + return Location{ + StorageName: a.GetStorageType(), + Location: a.Region, + } +} + +func (a *COSType) Equals(other StorageType) bool { + o, ok := other.(*COSType) + if !ok { + return false + } + return a.Region == o.Region && a.Endpoint == o.Endpoint && a.Bucket == o.Bucket +} + func (a *COSType) String() string { return "COS" } @@ -119,12 +189,28 @@ func (a *COSType) String() string { type EFileType struct { serder.Metadata `union:"EFile"` Type string `json:"type"` + ClusterID string `json:"clusterID"` } func (a *EFileType) GetStorageType() string { return "EFile" } +func (a *EFileType) GetLocation() Location { + return Location{ + StorageName: a.GetStorageType(), + Location: a.ClusterID, + } +} + +func (a *EFileType) Equals(other StorageType) bool { + o, ok := other.(*EFileType) + if !ok { + return false + } + return a.ClusterID == o.ClusterID +} + func (a *EFileType) String() string { return "EFile" } @@ -133,16 +219,34 @@ func (a *EFileType) String() string { type S3Type struct { serder.Metadata `union:"S3"` Type string `json:"type"` + Region string `json:"region"` + Endpoint string `json:"endpoint"` + Bucket string `json:"bucket"` } func (a *S3Type) GetStorageType() string { return "S3" } +func (a *S3Type) GetLocation() Location { + return Location{ + StorageName: a.GetStorageType(), + Location: a.Region, + } +} + func (a *S3Type) String() string { return "S3" } +func (a *S3Type) Equals(other StorageType) bool { + o, ok := other.(*S3Type) + if !ok { + return false + } + return a.Region == o.Region && a.Endpoint == o.Endpoint && a.Bucket == o.Bucket +} + type ShardStoreUserConfig struct { BaseDir string `json:"baseDir"` MaxSize int64 `json:"maxSize"` diff --git a/coordinator/types/storage_credential.go b/coordinator/types/storage_credential.go index 8af6e41..93ed77f 100644 --- a/coordinator/types/storage_credential.go +++ b/coordinator/types/storage_credential.go @@ -11,7 +11,7 @@ type StorageCredential interface { var _ = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[StorageCredential]( (*LocalCred)(nil), - (*MashupCred)(nil), + // (*MashupCred)(nil), (*OBSCred)(nil), (*OSSCred)(nil), (*COSCred)(nil), @@ -26,45 +26,35 @@ type LocalCred struct { RootDir string `json:"rootDir"` } -type MashupCred struct { - StorageCredential `json:"-"` - serder.Metadata `union:"Mashup"` - Store StorageCredential `json:"store"` - Feature StorageCredential `json:"feature"` -} +// type MashupCred struct { +// StorageCredential `json:"-"` +// serder.Metadata `union:"Mashup"` +// Store StorageCredential `json:"store"` +// Feature StorageCredential `json:"feature"` +// } type OSSCred struct { StorageCredential `json:"-"` serder.Metadata `union:"OSS"` Type string `json:"type"` - Region string `json:"region"` AK string `json:"accessKeyId"` SK string `json:"secretAccessKey"` - Endpoint string `json:"endpoint"` - Bucket string `json:"bucket"` } type OBSCred struct { StorageCredential `json:"-"` serder.Metadata `union:"OBS"` Type string `json:"type"` - Region string `json:"region"` AK string `json:"accessKeyId"` SK string `json:"secretAccessKey"` - Endpoint string `json:"endpoint"` - Bucket string `json:"bucket"` - ProjectID string `json:"projectID"` } type COSCred struct { StorageCredential `json:"-"` serder.Metadata `union:"COS"` Type string `json:"type"` - Region string `json:"region"` AK string `json:"accessKeyId"` SK string `json:"secretAccessKey"` - Endpoint string `json:"endpoint"` - Bucket string `json:"bucket"` } type EFileCred struct { @@ -77,7 +67,6 @@ type EFileCred struct { User string `json:"user"` Password string `json:"password"` OrgID string `json:"orgID"` - ClusterID string `json:"clusterID"` } // 通用的S3协议的存储服务 @@ -85,9 +74,6 @@ type S3Cred struct { StorageCredential `json:"-"` serder.Metadata `union:"S3"` Type string `json:"type"` - Region string `json:"region"` AK string `json:"accessKeyId"` SK string `json:"secretAccessKey"` - Endpoint string `json:"endpoint"` - Bucket string `json:"bucket"` } diff --git a/coordinator/types/types.go b/coordinator/types/types.go index 1a889bd..1af7f88 100644 --- a/coordinator/types/types.go +++ b/coordinator/types/types.go @@ -71,15 +71,6 @@ func (HubConnectivity) TableName() string { return "HubConnectivity" } -type Location struct { - LocationID LocationID `gorm:"column:LocationID; primaryKey; type:bigint; autoIncrement" json:"locationID"` - Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` -} - -func (Location) TableName() string { - return "Location" -} - type User struct { UserID UserID `gorm:"column:UserID; primaryKey; type:bigint; autoIncrement" json:"userID"` Name string `gorm:"column:Name; type:varchar(255); not null" json:"name"` @@ -88,3 +79,13 @@ type User struct { func (User) TableName() string { return "User" } + +type HubLocation struct { + HubID HubID `gorm:"column:HubID; primaryKey; type:bigint" json:"hubID"` + StorageName string `gorm:"column:StorageName; type:varchar(255); not null" json:"storageName"` + Location string `gorm:"column:Location; type:varchar(255); not null" json:"location"` +} + +func (HubLocation) TableName() string { + return "HubLocation" +} diff --git a/hub/internal/rpc/user_space.go b/hub/internal/rpc/user_space.go index 021a95c..473d134 100644 --- a/hub/internal/rpc/user_space.go +++ b/hub/internal/rpc/user_space.go @@ -9,8 +9,8 @@ import ( hubrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/hub" ) -func (svc *Service) PublicStoreListAll(context context.Context, msg *hubrpc.PublicStoreListAll) (*hubrpc.PublicStoreListAllResp, *rpc.CodeError) { - pub, err := svc.stgPool.GetPublicStore(&msg.UserSpace) +func (svc *Service) BaseStoreListAll(context context.Context, msg *hubrpc.BaseStoreListAll) (*hubrpc.BaseStoreListAllResp, *rpc.CodeError) { + pub, err := svc.stgPool.GetBaseStore(&msg.UserSpace) if err != nil { return nil, rpc.Failed(errorcode.OperationFailed, err.Error()) } @@ -20,13 +20,13 @@ func (svc *Service) PublicStoreListAll(context context.Context, msg *hubrpc.Publ return nil, rpc.Failed(errorcode.OperationFailed, err.Error()) } - return &hubrpc.PublicStoreListAllResp{ + return &hubrpc.BaseStoreListAllResp{ Entries: es, }, nil } -func (svc *Service) PublicStoreMkdirs(context context.Context, msg *hubrpc.PublicStoreMkdirs) (*hubrpc.PublicStoreMkdirsResp, *rpc.CodeError) { - pub, err := svc.stgPool.GetPublicStore(&msg.UserSpace) +func (svc *Service) BaseStoreMkdirs(context context.Context, msg *hubrpc.BaseStoreMkdirs) (*hubrpc.BaseStoreMkdirsResp, *rpc.CodeError) { + pub, err := svc.stgPool.GetBaseStore(&msg.UserSpace) if err != nil { return nil, rpc.Failed(errorcode.OperationFailed, err.Error()) } @@ -41,7 +41,7 @@ func (svc *Service) PublicStoreMkdirs(context context.Context, msg *hubrpc.Publi } } - return &hubrpc.PublicStoreMkdirsResp{ + return &hubrpc.BaseStoreMkdirsResp{ Successes: suc, }, nil }