package metacache import ( "context" "time" "gitlink.org.cn/cloudream/common/pkgs/logger" stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals" corrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/coordinator" jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types" ) func (m *MetaCacheHost) AddStorageMeta() *UserSpaceMeta { meta := &UserSpaceMeta{ host: m, } meta.cache = NewSimpleMetaCache(SimpleMetaCacheConfig[jcstypes.UserSpaceID, jcstypes.UserSpaceDetail]{ Getter: meta.load, Expire: time.Minute * 5, }) m.caches = append(m.caches, meta) return meta } type UserSpaceMeta struct { host *MetaCacheHost cache *SimpleMetaCache[jcstypes.UserSpaceID, jcstypes.UserSpaceDetail] } func (s *UserSpaceMeta) Get(spaceID jcstypes.UserSpaceID) *jcstypes.UserSpaceDetail { v, ok := s.cache.Get(spaceID) if ok { return &v } return nil } func (s *UserSpaceMeta) GetMany(spaceIDs []jcstypes.UserSpaceID) []*jcstypes.UserSpaceDetail { vs, oks := s.cache.GetMany(spaceIDs) ret := make([]*jcstypes.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) Drop(keys []jcstypes.UserSpaceID) { s.cache.Drop(keys) } func (s *UserSpaceMeta) load(keys []jcstypes.UserSpaceID) ([]jcstypes.UserSpaceDetail, []bool) { vs := make([]jcstypes.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[jcstypes.UserSpaceID]*jcstypes.UserSpaceDetail) for i := range spaces { detailMap[spaces[i].UserSpaceID] = &jcstypes.UserSpaceDetail{ UserID: stgglb.UserID, UserSpace: spaces[i], } } if !stgglb.StandaloneMode { coorCli := stgglb.CoordinatorRPCPool.Get() defer coorCli.Release() stgs := make([]jcstypes.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 }