package metacache import ( "context" "time" "gitlink.org.cn/cloudream/common/pkgs/logger" "gitlink.org.cn/cloudream/jcs-pub/client/types" stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals" corrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/coordinator" cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types" ) func (m *MetaCacheHost) AddStorageMeta() *UserSpaceMeta { meta := &UserSpaceMeta{ host: m, } meta.cache = NewSimpleMetaCache(SimpleMetaCacheConfig[types.UserSpaceID, types.UserSpaceDetail]{ Getter: meta.load, Expire: time.Minute * 5, }) m.caches = append(m.caches, meta) return meta } type UserSpaceMeta struct { host *MetaCacheHost cache *SimpleMetaCache[types.UserSpaceID, types.UserSpaceDetail] } func (s *UserSpaceMeta) Get(spaceID types.UserSpaceID) *types.UserSpaceDetail { v, ok := s.cache.Get(spaceID) if ok { return &v } return nil } func (s *UserSpaceMeta) GetMany(spaceIDs []types.UserSpaceID) []*types.UserSpaceDetail { vs, oks := s.cache.GetMany(spaceIDs) ret := make([]*types.UserSpaceDetail, len(vs)) for i := range vs { if oks[i] { ret[i] = &vs[i] } } return ret } func (s *UserSpaceMeta) ClearOutdated() { s.cache.ClearOutdated() } func (s *UserSpaceMeta) load(keys []types.UserSpaceID) ([]types.UserSpaceDetail, []bool) { vs := make([]types.UserSpaceDetail, len(keys)) oks := make([]bool, len(keys)) spaces, err := s.host.db.UserSpace().BatchGetByID(s.host.db.DefCtx(), keys) if err != nil { logger.Warnf("batch get user space by id: %v", err) return vs, oks } detailMap := make(map[types.UserSpaceID]*types.UserSpaceDetail) for i := range spaces { detailMap[spaces[i].UserSpaceID] = &types.UserSpaceDetail{ UserID: stgglb.Local.UserID, UserSpace: spaces[i], } } if !stgglb.StandaloneMode { coorCli := stgglb.CoordinatorRPCPool.Get() defer coorCli.Release() stgs := make([]cortypes.StorageType, len(spaces)) for i := range spaces { stgs[i] = spaces[i].Storage } 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 { detailMap[spaces[i].UserSpaceID].RecommendHub = selectHubs.Hubs[i] } } for i := range keys { if detail, ok := detailMap[keys[i]]; ok { vs[i] = *detail oks[i] = true } } return vs, oks }