Skip to content

Commit c151486

Browse files
committed
add memory cache for api keys
1 parent 7d2a21b commit c151486

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
lines changed

api/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/cloudevents/sdk-go/v2 v2.14.0
1414
github.com/cockroachdb/cockroach-go/v2 v2.3.5
1515
github.com/davecgh/go-spew v1.1.1
16+
github.com/dgraph-io/ristretto v0.1.1
1617
github.com/gofiber/fiber/v2 v2.48.0
1718
github.com/gofiber/swagger v0.1.12
1819
github.com/golang-jwt/jwt v3.2.2+incompatible
@@ -70,13 +71,15 @@ require (
7071
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
7172
github.com/cespare/xxhash/v2 v2.2.0 // indirect
7273
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
74+
github.com/dustin/go-humanize v1.0.0 // indirect
7375
github.com/go-logr/logr v1.2.4 // indirect
7476
github.com/go-logr/stdr v1.2.2 // indirect
7577
github.com/go-openapi/jsonpointer v0.20.0 // indirect
7678
github.com/go-openapi/jsonreference v0.20.2 // indirect
7779
github.com/go-openapi/spec v0.20.9 // indirect
7880
github.com/go-openapi/swag v0.22.4 // indirect
7981
github.com/go-sql-driver/mysql v1.7.1 // indirect
82+
github.com/golang/glog v1.1.1 // indirect
8083
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
8184
github.com/golang/protobuf v1.5.3 // indirect
8285
github.com/google/go-cmp v0.5.9 // indirect

api/go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
9191
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9292
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9393
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
94+
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
95+
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
96+
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
97+
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
9498
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
9599
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
100+
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
101+
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
96102
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
97103
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
98104
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -140,6 +146,7 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
140146
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
141147
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
142148
github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw=
149+
github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
143150
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
144151
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
145152
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -311,6 +318,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
311318
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
312319
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
313320
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
321+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
314322
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
315323
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
316324
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -458,6 +466,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
458466
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
459467
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
460468
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
469+
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
461470
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
462471
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
463472
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

api/pkg/di/container.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"strconv"
1010
"time"
1111

12+
"github.com/dgraph-io/ristretto"
13+
1214
"gorm.io/plugin/opentelemetry/tracing"
1315

1416
"github.com/NdoleStudio/httpsms/pkg/discord"
@@ -1131,10 +1133,25 @@ func (container *Container) UserRepository() repositories.UserRepository {
11311133
return repositories.NewGormUserRepository(
11321134
container.Logger(),
11331135
container.Tracer(),
1136+
container.RistrettoCache(),
11341137
container.DB(),
11351138
)
11361139
}
11371140

1141+
// RistrettoCache creates an in-memory *ristretto.Cache
1142+
func (container *Container) RistrettoCache() (cache *ristretto.Cache) {
1143+
container.logger.Debug(fmt.Sprintf("creating %T", cache))
1144+
ristrettoCache, err := ristretto.NewCache(&ristretto.Config{
1145+
MaxCost: 5000,
1146+
NumCounters: 5000 * 10,
1147+
BufferItems: 64,
1148+
})
1149+
if err != nil {
1150+
container.logger.Fatal(stacktrace.Propagate(err, "cannot create ristretto cache"))
1151+
}
1152+
return ristrettoCache
1153+
}
1154+
11381155
// InitializeTraceProvider initializes the open telemetry trace provider
11391156
func (container *Container) InitializeTraceProvider() func() {
11401157
return container.initializeUptraceProvider(container.version, container.projectID)

api/pkg/repositories/gorm_user_repository.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"github.com/cockroachdb/cockroach-go/v2/crdb/crdbgorm"
12+
"github.com/dgraph-io/ristretto"
1213

1314
"github.com/NdoleStudio/httpsms/pkg/entities"
1415
"github.com/NdoleStudio/httpsms/pkg/telemetry"
@@ -20,13 +21,15 @@ import (
2021
type gormUserRepository struct {
2122
logger telemetry.Logger
2223
tracer telemetry.Tracer
24+
cache *ristretto.Cache
2325
db *gorm.DB
2426
}
2527

2628
// NewGormUserRepository creates the GORM version of the UserRepository
2729
func NewGormUserRepository(
2830
logger telemetry.Logger,
2931
tracer telemetry.Tracer,
32+
cache *ristretto.Cache,
3033
db *gorm.DB,
3134
) UserRepository {
3235
return &gormUserRepository{
@@ -83,9 +86,14 @@ func (repository *gormUserRepository) Update(ctx context.Context, user *entities
8386
}
8487

8588
func (repository *gormUserRepository) LoadAuthUser(ctx context.Context, apiKey string) (entities.AuthUser, error) {
86-
ctx, span := repository.tracer.Start(ctx)
89+
ctx, span, ctxLogger := repository.tracer.StartWithLogger(ctx, repository.logger)
8790
defer span.End()
8891

92+
if authUser, found := repository.cache.Get(apiKey); found {
93+
ctxLogger.Info(fmt.Sprintf("cache hit for user with ID [%s]", authUser.(entities.AuthUser).ID))
94+
return authUser.(entities.AuthUser), nil
95+
}
96+
8997
user := new(entities.User)
9098
err := repository.db.WithContext(ctx).Where("api_key = ?", apiKey).First(user).Error
9199
if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -98,10 +106,17 @@ func (repository *gormUserRepository) LoadAuthUser(ctx context.Context, apiKey s
98106
return entities.AuthUser{}, repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
99107
}
100108

101-
return entities.AuthUser{
109+
authUser := entities.AuthUser{
102110
ID: user.ID,
103111
Email: user.Email,
104-
}, nil
112+
}
113+
114+
if result := repository.cache.SetWithTTL(apiKey, authUser, 1, 2*time.Hour); !result {
115+
msg := fmt.Sprintf("cannot cache [%T] with ID [%s]", authUser, user.ID)
116+
ctxLogger.Error(repository.tracer.WrapErrorSpan(span, stacktrace.NewError(msg)))
117+
}
118+
119+
return authUser, nil
105120
}
106121

107122
func (repository *gormUserRepository) Load(ctx context.Context, userID entities.UserID) (*entities.User, error) {

0 commit comments

Comments
 (0)