diff options
author | feistel <6742251-feistel@users.noreply.gitlab.com> | 2021-11-25 15:40:11 +0300 |
---|---|---|
committer | feistel <6742251-feistel@users.noreply.gitlab.com> | 2021-11-25 15:40:11 +0300 |
commit | b0dc301ecb87b7ee3b3fe7680c326a266c930a9c (patch) | |
tree | c7be9c0e6bd5bf641113597a966a672988f0840a | |
parent | 35c52c2476db8524f5d4e3c2c402522e449d74ef (diff) |
refactor: add functional option to customize lru cache size and expiration
don't expose default values and keep them private.
-rw-r--r-- | app.go | 2 | ||||
-rw-r--r-- | internal/lru/lru.go | 34 | ||||
-rw-r--r-- | internal/ratelimiter/middleware_test.go | 7 | ||||
-rw-r--r-- | internal/ratelimiter/ratelimiter_test.go | 10 | ||||
-rw-r--r-- | internal/vfs/zip/vfs.go | 8 |
5 files changed, 31 insertions, 30 deletions
@@ -267,8 +267,6 @@ func (a *theApp) buildHandlerPipeline() (http.Handler, error) { if a.config.RateLimit.SourceIPLimitPerSecond > 0 { rl := ratelimiter.New( lru.New("source_ip", - lru.DefaultSourceIPItems, - lru.DefaultSourceIPExpirationInterval, lru.WithCachedEntriesMetric(metrics.RateLimitSourceIPCachedEntries), lru.WithCachedRequestsMetric(metrics.RateLimitSourceIPCacheRequests), ), diff --git a/internal/lru/lru.go b/internal/lru/lru.go index c30573ae..741d9ad2 100644 --- a/internal/lru/lru.go +++ b/internal/lru/lru.go @@ -19,8 +19,8 @@ const itemsToPruneDiv = 16 // based on an avg ~4,000 unique IPs per minute // https://log.gprd.gitlab.net/app/lens#/edit/f7110d00-2013-11ec-8c8e-ed83b5469915?_g=h@e78830b -const DefaultSourceIPItems = 5000 -const DefaultSourceIPExpirationInterval = time.Minute +const defaultSourceIPItems = 5000 +const defaultSourceIPExpirationInterval = time.Minute // Option function to configure a Cache type Option func(*Cache) @@ -29,21 +29,27 @@ type Option func(*Cache) type Cache struct { op string duration time.Duration + maxSize int64 cache *ccache.Cache metricCachedEntries *prometheus.GaugeVec metricCacheRequests *prometheus.CounterVec } // New creates an LRU cache -func New(op string, maxEntries int64, duration time.Duration, opts ...Option) *Cache { +func New(op string, opts ...Option) *Cache { c := &Cache{ op: op, - duration: duration, + duration: defaultSourceIPExpirationInterval, + maxSize: defaultSourceIPItems, + } + + for _, opt := range opts { + opt(c) } configuration := ccache.Configure() - configuration.MaxSize(maxEntries) - configuration.ItemsToPrune(uint32(maxEntries) / itemsToPruneDiv) + configuration.MaxSize(c.maxSize) + configuration.ItemsToPrune(uint32(c.maxSize) / itemsToPruneDiv) configuration.GetsPerPromote(getsPerPromote) // if item gets requested frequently promote it configuration.OnDelete(func(*ccache.Item) { if c.metricCachedEntries != nil { @@ -53,10 +59,6 @@ func New(op string, maxEntries int64, duration time.Duration, opts ...Option) *C c.cache = ccache.New(configuration) - for _, opt := range opts { - opt(c) - } - return c } @@ -103,3 +105,15 @@ func WithCachedRequestsMetric(m *prometheus.CounterVec) Option { c.metricCacheRequests = m } } + +func WithSourceIPExpirationInterval(t time.Duration) Option { + return func(c *Cache) { + c.duration = t + } +} + +func WithSourceIPItems(i int64) Option { + return func(c *Cache) { + c.maxSize = i + } +} diff --git a/internal/ratelimiter/middleware_test.go b/internal/ratelimiter/middleware_test.go index 132b24b9..6560956c 100644 --- a/internal/ratelimiter/middleware_test.go +++ b/internal/ratelimiter/middleware_test.go @@ -29,10 +29,7 @@ func TestSourceIPLimiterWithDifferentLimits(t *testing.T) { for tn, tc := range sharedTestCases { t.Run(tn, func(t *testing.T) { rl := New( - lru.New("source_ip", - lru.DefaultSourceIPItems, - lru.DefaultSourceIPExpirationInterval, - ), + lru.New("source_ip"), WithNow(mockNow), WithSourceIPLimitPerSecond(tc.sourceIPLimit), WithSourceIPBurstSize(tc.sourceIPBurstSize), @@ -89,8 +86,6 @@ func TestSourceIPLimiterDenyRequestsAfterBurst(t *testing.T) { t.Run(tn, func(t *testing.T) { rl := New( lru.New("source_ip", - lru.DefaultSourceIPItems, - lru.DefaultSourceIPExpirationInterval, lru.WithCachedEntriesMetric(cachedEntries), lru.WithCachedRequestsMetric(cacheReqs), ), diff --git a/internal/ratelimiter/ratelimiter_test.go b/internal/ratelimiter/ratelimiter_test.go index 5fb9ef2b..a85663af 100644 --- a/internal/ratelimiter/ratelimiter_test.go +++ b/internal/ratelimiter/ratelimiter_test.go @@ -53,10 +53,7 @@ func TestSourceIPAllowed(t *testing.T) { for tn, tc := range sharedTestCases { t.Run(tn, func(t *testing.T) { rl := New( - lru.New("source_ip", - lru.DefaultSourceIPItems, - lru.DefaultSourceIPExpirationInterval, - ), + lru.New("source_ip"), WithNow(mockNow), WithSourceIPLimitPerSecond(tc.sourceIPLimit), WithSourceIPBurstSize(tc.sourceIPBurstSize), @@ -80,10 +77,7 @@ func TestSingleRateLimiterWithMultipleSourceIPs(t *testing.T) { rate := 10 * time.Millisecond rl := New( - lru.New("source_ip", - lru.DefaultSourceIPItems, - lru.DefaultSourceIPExpirationInterval, - ), + lru.New("source_ip"), WithSourceIPLimitPerSecond(float64(1/rate)), WithSourceIPBurstSize(1), ) diff --git a/internal/vfs/zip/vfs.go b/internal/vfs/zip/vfs.go index 67fe94dc..24d32163 100644 --- a/internal/vfs/zip/vfs.go +++ b/internal/vfs/zip/vfs.go @@ -86,15 +86,15 @@ func New(cfg *config.ZipServing) vfs.VFS { // TODO: To be removed with https://gitlab.com/gitlab-org/gitlab-pages/-/issues/480 zipVFS.dataOffsetCache = lru.New( "data-offset", - defaultDataOffsetItems, - defaultDataOffsetExpirationInterval, + lru.WithSourceIPItems(defaultDataOffsetItems), + lru.WithSourceIPExpirationInterval(defaultDataOffsetExpirationInterval), lru.WithCachedEntriesMetric(metrics.ZipCachedEntries), lru.WithCachedRequestsMetric(metrics.ZipCacheRequests), ) zipVFS.readlinkCache = lru.New( "readlink", - defaultReadlinkItems, - defaultReadlinkExpirationInterval, + lru.WithSourceIPItems(defaultReadlinkItems), + lru.WithSourceIPExpirationInterval(defaultReadlinkExpirationInterval), lru.WithCachedEntriesMetric(metrics.ZipCachedEntries), lru.WithCachedRequestsMetric(metrics.ZipCacheRequests), ) |