package frostfs import ( "context" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/cache" "git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/handler" "git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/logs" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" "go.uber.org/zap" ) type Source struct { frostFS *FrostFS netMapCache *cache.NetMapCache bucketCache *cache.BucketCache log *zap.Logger } func NewSource(frostFS *FrostFS, netMapCache *cache.NetMapCache, bucketCache *cache.BucketCache, log *zap.Logger) *Source { return &Source{ frostFS: frostFS, netMapCache: netMapCache, bucketCache: bucketCache, log: log, } } func (s *Source) NetMapSnapshot(ctx context.Context) (netmap.NetMap, error) { cachedNetMap := s.netMapCache.Get() if cachedNetMap != nil { return *cachedNetMap, nil } netMap, err := s.frostFS.NetMapSnapshot(ctx) if err != nil { return netmap.NetMap{}, fmt.Errorf("get net map: %w", err) } if err = s.netMapCache.Put(netMap); err != nil { s.log.Warn(logs.CouldntCacheNetMap, zap.Error(err)) } return netMap, nil } func (s *Source) PlacementPolicy(ctx context.Context, cnrID cid.ID) (netmap.PlacementPolicy, error) { info := s.bucketCache.GetByCID(cnrID) if info != nil { return info.PlacementPolicy, nil } prm := handler.PrmContainer{ ContainerID: cnrID, } res, err := s.frostFS.Container(ctx, prm) if err != nil { return netmap.PlacementPolicy{}, fmt.Errorf("get container: %w", err) } // We don't put container back to the cache to keep cache // coherent to the requests made by users. FrostFS Source // is being used by SDK Tree Pool and it should not fill cache // with possibly irrelevant container values. return res.PlacementPolicy(), nil }