From cd50e9b4bcf3d9115f83837a3efab036b1548e0f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 19 Apr 2024 09:45:14 -0700 Subject: [PATCH] make LRU cache global for internode tokens (#19555) --- cmd/jwt.go | 40 ++++++++++++++++++---------------------- cmd/jwt_test.go | 5 ++--- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/cmd/jwt.go b/cmd/jwt.go index 911752ced..8a91b763d 100644 --- a/cmd/jwt.go +++ b/cmd/jwt.go @@ -50,29 +50,12 @@ var ( errMalformedAuth = errors.New("Malformed authentication input") ) -// cachedAuthenticateNode will cache authenticateNode results for given values up to ttl. -func cachedAuthenticateNode(ttl time.Duration) func(accessKey, secretKey, audience string) (string, error) { - type key struct { - accessKey, secretKey, audience string - } - - cache := expirable.NewLRU[key, string](100, nil, ttl) - return func(accessKey, secretKey, audience string) (s string, err error) { - k := key{accessKey: accessKey, secretKey: secretKey, audience: audience} - - var ok bool - s, ok = cache.Get(k) - if !ok { - s, err = authenticateNode(accessKey, secretKey, audience) - if err != nil { - return "", err - } - cache.Add(k, s) - } - return s, nil - } +type cacheKey struct { + accessKey, secretKey, audience string } +var cacheLRU = expirable.NewLRU[cacheKey, string](1000, nil, 15*time.Second) + func authenticateNode(accessKey, secretKey, audience string) (string, error) { claims := xjwt.NewStandardClaims() claims.SetExpiry(UTCNow().Add(defaultInterNodeJWTExpiry)) @@ -161,7 +144,20 @@ func metricsRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, []string, b // newCachedAuthToken returns a token that is cached up to 15 seconds. // If globalActiveCred is updated it is reflected at once. func newCachedAuthToken() func(audience string) string { - fn := cachedAuthenticateNode(15 * time.Second) + fn := func(accessKey, secretKey, audience string) (s string, err error) { + k := cacheKey{accessKey: accessKey, secretKey: secretKey, audience: audience} + + var ok bool + s, ok = cacheLRU.Get(k) + if !ok { + s, err = authenticateNode(accessKey, secretKey, audience) + if err != nil { + return "", err + } + cacheLRU.Add(k, s) + } + return s, nil + } return func(audience string) string { cred := globalActiveCred token, err := fn(cred.AccessKey, cred.SecretKey, audience) diff --git a/cmd/jwt_test.go b/cmd/jwt_test.go index 2e74547f0..24b66df94 100644 --- a/cmd/jwt_test.go +++ b/cmd/jwt_test.go @@ -22,7 +22,6 @@ import ( "net/http" "os" "testing" - "time" jwtgo "github.com/golang-jwt/jwt/v4" xjwt "github.com/minio/minio/internal/jwt" @@ -181,11 +180,11 @@ func BenchmarkAuthenticateNode(b *testing.B) { } }) b.Run("cached", func(b *testing.B) { - fn := cachedAuthenticateNode(time.Second) + fn := newCachedAuthToken() b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - fn(creds.AccessKey, creds.SecretKey, "aud") + fn("aud") } }) }