package frostfs import ( "context" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" ) type Source struct { frostFS *FrostFS cache *layer.Cache } func NewSource(frostFS *FrostFS, cache *layer.Cache) *Source { return &Source{ frostFS: frostFS, cache: cache, } } func (s *Source) NetMapSnapshot(ctx context.Context) (netmap.NetMap, error) { cachedNetmap := s.cache.GetNetmap() if cachedNetmap != nil { return *cachedNetmap, nil } netmapSnapshot, err := s.frostFS.NetmapSnapshot(ctx) if err != nil { return netmap.NetMap{}, fmt.Errorf("get netmap: %w", err) } s.cache.PutNetmap(netmapSnapshot) return netmapSnapshot, nil } func (s *Source) PlacementPolicy(ctx context.Context, cnrID cid.ID) (netmap.PlacementPolicy, error) { cachedPolicy := s.cache.GetPlacementPolicy(cnrID) if cachedPolicy != nil { return *cachedPolicy, nil } prm := frostfs.PrmContainer{ ContainerID: cnrID, } if bd, err := middleware.GetBoxData(ctx); err == nil && bd.Gate != nil { prm.SessionToken = bd.Gate.SessionToken() } 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 S3 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 }