FeatureToggle: for storing signed in user object in a Remote Cache (#59883)

* FeatureToggle: for storing sessions in a Remote Cache

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>

* Fix conflicting modifications :D

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>

* rename the flag to userRemoteCache

* undo unintended change

* Users: Add option to use remote cache for SignedInUsers (#59892)

* Add remote cache to GetSignedInUserWithCacheCtx

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>

* Populate SignedInUser remote cache

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>

* Line

* minor fixes to make this work

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>

* Fix tests

* change flag to updated name

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>

Co-authored-by: ievaVasiljeva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Gabriel MABILLE
2022-12-07 08:58:15 +01:00
committed by GitHub
co-authored by ievaVasiljeva
parent 3c86bf550e
commit 91b15eed1a
7 changed files with 48 additions and 4 deletions
@@ -67,5 +67,6 @@ export interface FeatureToggles {
redshiftAsyncQueryDataSupport?: boolean;
athenaAsyncQueryDataSupport?: boolean;
increaseInMemDatabaseQueryCache?: boolean;
userRemoteCache?: boolean;
datasourceLogger?: boolean;
}
+6
View File
@@ -362,6 +362,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, nil, nil, nil,
nil, nil, nil, nil, nil, hs.SQLStore.(*sqlstore.SQLStore),
nil, featuremgmt.WithFeatures(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
})
@@ -467,6 +468,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, nil, nil, nil,
nil, nil, nil, nil, nil, hs.SQLStore.(*sqlstore.SQLStore),
nil, featuremgmt.WithFeatures(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
})
@@ -573,6 +575,7 @@ func TestPostOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, nil, nil, nil,
nil, nil, nil, nil, nil, hs.SQLStore.(*sqlstore.SQLStore),
nil, featuremgmt.WithFeatures(),
)
})
setupOrgUsersDBForAccessControlTests(t, sc.db)
@@ -699,6 +702,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, nil, nil, nil,
nil, nil, nil, nil, nil, hs.SQLStore.(*sqlstore.SQLStore),
nil, featuremgmt.WithFeatures(),
)
})
setInitCtxSignedInViewer(sc.initCtx)
@@ -818,6 +822,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, nil, nil, nil,
nil, nil, nil, nil, nil, hs.SQLStore.(*sqlstore.SQLStore),
nil, featuremgmt.WithFeatures(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
})
@@ -946,6 +951,7 @@ func TestDeleteOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, nil, nil, nil,
nil, nil, nil, nil, nil, hs.SQLStore.(*sqlstore.SQLStore),
nil, featuremgmt.WithFeatures(),
)
})
setupOrgUsersDBForAccessControlTests(t, sc.db)
+5
View File
@@ -283,6 +283,11 @@ var (
Name: "increaseInMemDatabaseQueryCache",
Description: "Enable more in memory caching for database queries",
},
{
Name: "userRemoteCache",
Description: "Enable using remote cache for users",
State: FeatureStateAlpha,
},
{
Name: "datasourceLogger",
Description: "Logs all datasource requests",
+4
View File
@@ -211,6 +211,10 @@ const (
// Enable more in memory caching for database queries
FlagIncreaseInMemDatabaseQueryCache = "increaseInMemDatabaseQueryCache"
// FlagUserRemoteCache
// Enable using remote cache for users
FlagUserRemoteCache = "userRemoteCache"
// FlagDatasourceLogger
// Logs all datasource requests
FlagDatasourceLogger = "datasourceLogger"
+3 -3
View File
@@ -475,12 +475,12 @@ func (ss *SQLStore) GetUserOrgList(ctx context.Context, query *models.GetUserOrg
})
}
func newSignedInUserCacheKey(orgID, userID int64) string {
func NewSignedInUserCacheKey(orgID, userID int64) string {
return fmt.Sprintf("signed-in-user-%d-%d", userID, orgID)
}
func (ss *SQLStore) GetSignedInUserWithCacheCtx(ctx context.Context, query *models.GetSignedInUserQuery) error {
cacheKey := newSignedInUserCacheKey(query.OrgId, query.UserId)
cacheKey := NewSignedInUserCacheKey(query.OrgId, query.UserId)
if cached, found := ss.CacheService.Get(cacheKey); found {
cachedUser := cached.(user.SignedInUser)
query.Result = &cachedUser
@@ -492,7 +492,7 @@ func (ss *SQLStore) GetSignedInUserWithCacheCtx(ctx context.Context, query *mode
return err
}
cacheKey = newSignedInUserCacheKey(query.Result.OrgID, query.UserId)
cacheKey = NewSignedInUserCacheKey(query.Result.OrgID, query.UserId)
ss.CacheService.Set(cacheKey, *query.Result, time.Second*5)
return nil
}
+1 -1
View File
@@ -457,7 +457,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.NotNil(t, query4.Result)
require.Equal(t, query4.Result.OrgID, users[0].OrgID)
cacheKey := newSignedInUserCacheKey(query4.Result.OrgID, query4.UserId)
cacheKey := NewSignedInUserCacheKey(query4.Result.OrgID, query4.UserId)
_, found := ss.CacheService.Get(cacheKey)
require.True(t, found)
+28
View File
@@ -5,9 +5,11 @@ import (
"errors"
"time"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/quota"
@@ -33,6 +35,8 @@ type Service struct {
userAuthService userauth.Service
quotaService quota.Service
accessControlStore accesscontrol.Service
remoteCache *remotecache.RemoteCache
features *featuremgmt.FeatureManager
// TODO remove sqlstore
sqlStore *sqlstore.SQLStore
@@ -51,7 +55,13 @@ func ProvideService(
accessControlStore accesscontrol.Service,
cfg *setting.Cfg,
ss *sqlstore.SQLStore,
remoteCache *remotecache.RemoteCache,
features *featuremgmt.FeatureManager,
) user.Service {
if features.IsEnabled(featuremgmt.FlagUserRemoteCache) {
remotecache.Register(user.SignedInUser{})
}
return &Service{
store: &sqlStore{
db: db,
@@ -67,6 +77,8 @@ func ProvideService(
accessControlStore: accessControlStore,
cfg: cfg,
sqlStore: ss,
remoteCache: remoteCache,
features: features,
}
}
@@ -309,6 +321,17 @@ func (s *Service) SetUsingOrg(ctx context.Context, cmd *user.SetUsingOrgCommand)
// TODO: remove wrapper around sqlstore
func (s *Service) GetSignedInUserWithCacheCtx(ctx context.Context, query *user.GetSignedInUserQuery) (*user.SignedInUser, error) {
// Fetching from remote cache first otherwise fallback to in memory cache
cacheKey := sqlstore.NewSignedInUserCacheKey(query.OrgID, query.UserID)
if s.features.IsEnabled(featuremgmt.FlagUserRemoteCache) {
res, errCache := s.remoteCache.Get(ctx, cacheKey)
if errCache == nil {
if signedInUser, ok := res.(user.SignedInUser); ok {
return &signedInUser, nil
}
}
}
q := &models.GetSignedInUserQuery{
UserId: query.UserID,
Login: query.Login,
@@ -319,6 +342,11 @@ func (s *Service) GetSignedInUserWithCacheCtx(ctx context.Context, query *user.G
if err != nil {
return nil, err
}
// Remember user in remote cache
if s.features.IsEnabled(featuremgmt.FlagUserRemoteCache) {
_ = s.remoteCache.Set(ctx, cacheKey, *(q.Result), time.Second*5)
}
return q.Result, nil
}