From 3bc1229062cf44e08171f00ab74a62e40a960d5b Mon Sep 17 00:00:00 2001 From: Dmitrii Stepanov Date: Mon, 17 Jun 2024 09:32:20 +0300 Subject: [PATCH] [#146] native: Add NetworkInfo cache Signed-off-by: Dmitrii Stepanov --- internal/native/cache.go | 58 +++++++++++++++++++++++++++++++++++++++ internal/native/client.go | 6 ++-- 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 internal/native/cache.go diff --git a/internal/native/cache.go b/internal/native/cache.go new file mode 100644 index 0000000..48ce507 --- /dev/null +++ b/internal/native/cache.go @@ -0,0 +1,58 @@ +package native + +import ( + "context" + "sync" + "time" + + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" +) + +const networkCacheTTL = time.Minute + +var networkInfoCache = &networkInfoCacheT{} + +type networkInfoCacheT struct { + guard sync.RWMutex + current *netmap.NetworkInfo + fetchTS time.Time +} + +func (c *networkInfoCacheT) getOrFetch(ctx context.Context, cli *client.Client) (*netmap.NetworkInfo, error) { + if v := c.get(); v != nil { + return v, nil + } + return c.fetch(ctx, cli) +} + +func (c *networkInfoCacheT) get() *netmap.NetworkInfo { + c.guard.RLock() + defer c.guard.RUnlock() + + if c.current == nil || time.Since(c.fetchTS) > networkCacheTTL { + return nil + } + + return c.current +} + +func (c *networkInfoCacheT) fetch(ctx context.Context, cli *client.Client) (*netmap.NetworkInfo, error) { + c.guard.Lock() + defer c.guard.Unlock() + + if time.Since(c.fetchTS) <= networkCacheTTL { + return c.current, nil + } + + res, err := cli.NetworkInfo(ctx, client.PrmNetworkInfo{}) + if err != nil { + return nil, err + } + + v := res.Info() + c.current = &v + c.fetchTS = time.Now() + + return c.current, nil +} diff --git a/internal/native/client.go b/internal/native/client.go index 944bd66..d8fa518 100644 --- a/internal/native/client.go +++ b/internal/native/client.go @@ -437,12 +437,12 @@ func put(vu modules.VU, cli *client.Client, prepareLocally bool, tok *session.Ob prm.MaxChunkLength = chunkSize } if prepareLocally { - res, err := cli.NetworkInfo(vu.Context(), client.PrmNetworkInfo{}) + ni, err := networkInfoCache.getOrFetch(vu.Context(), cli) if err != nil { return nil, err } - prm.MaxSize = res.Info().MaxObjectSize() - prm.EpochSource = epochSource(res.Info().CurrentEpoch()) + prm.MaxSize = ni.MaxObjectSize() + prm.EpochSource = epochSource(ni.CurrentEpoch()) prm.WithoutHomomorphHash = true if maxObjSize > 0 { prm.MaxSize = maxObjSize