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 } netmapSnapshot, err := s.frostFS.NetmapSnapshot(ctx) if err != nil { return netmap.NetMap{}, fmt.Errorf("get netmap: %w", err) } if err = s.netmapCache.Put(netmapSnapshot); err != nil { s.log.Warn(logs.CouldntCacheNetmap, zap.Error(err)) } return netmapSnapshot, 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 }