Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add CachedCheckResolver for caching Check subproblems #891

Merged
merged 29 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b56ed31
feat: add CachedCheckResolver for caching Check subproblems
adriantam Aug 1, 2023
d440830
feat: add configuration and unit test (#897)
adriantam Aug 1, 2023
59b972c
chore: rename mock_resolver to mock_check_resolver
adriantam Aug 1, 2023
c06d26a
fix: add flags for cache
adriantam Aug 1, 2023
9b30187
fix: add to flag
adriantam Aug 1, 2023
3537c5b
feat: add experimental flag
adriantam Aug 1, 2023
ba5f33b
fix: correct import path
adriantam Aug 1, 2023
280259e
fix: update based on code review feedback
adriantam Aug 2, 2023
fa5681b
fix: correct lint
adriantam Aug 2, 2023
9afde93
fix: correct flag discrepency
adriantam Aug 2, 2023
7d4349b
fix: use require.Nil instead
adriantam Aug 2, 2023
3b81459
chore: update flag name
adriantam Aug 2, 2023
a18aa05
chore: add additional unit test
adriantam Aug 2, 2023
f9f4f05
chore: do not save update metadata
adriantam Aug 4, 2023
8ba4fe0
fix: correct default check cache enable value
adriantam Aug 8, 2023
b93d477
fix: update based on code review feedback
adriantam Aug 9, 2023
3478d5b
fix: do not need tuple keys twice in calculating cache key
adriantam Aug 9, 2023
7cf4956
Merge branch 'main' of github.com:openfga/openfga into query-caching
adriantam Aug 14, 2023
4f6401e
fix: initial call to check resolver to use checkCache
adriantam Aug 14, 2023
c1b773a
chore: rename varaible as suggested by code review
adriantam Aug 14, 2023
a4df07e
fix: correct UT expectation
adriantam Aug 14, 2023
6b0fb20
Merge branch 'main' into query-caching
adriantam Aug 14, 2023
ce62319
fix: list object to use cache resolver without dispatch
adriantam Aug 15, 2023
230b868
Merge branch 'main' of github.com:openfga/openfga into query-caching
adriantam Aug 15, 2023
684f92c
chore: test reading of config
adriantam Aug 15, 2023
3cf5c61
fix: remove unused variable
adriantam Aug 16, 2023
d9c04f2
chore: add log info message when check resolver is enabled
adriantam Aug 16, 2023
82008eb
fix: simplified setup
adriantam Aug 17, 2023
7df0472
chore: simplified code by adding check options as parameter
adriantam Aug 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"type": "array",
"items": {
"type": "string",
"enum": []
"enum": ["check-query-cache"]
},
"default": [],
"x-env-variable": "OPENFGA_EXPERIMENTALS"
Expand Down Expand Up @@ -349,6 +349,30 @@
"x-env-variable": "OPENFGA_METRICS_ENABLE_RPC_HISTOGRAMS"
}
}
},
"checkQueryCache": {
"type": "object",
"properties": {
"enabled": {
"description": "when executing Check and ListObjects requests, enables caching. This will turn Check and ListObjects responses into eventually consistent responses",
"type": "bool",
"default": "false",
"x-env-variable": "OPENFGA_CHECK_QUERY_CACHE_ENABLED"
},
"limit": {
"description": "if caching of Check and ListObjects calls is enabled, this is the size limit (in items) of the cache",
"type": "integer",
"default": "10000",
"x-env-variable": "OPENFGA_CHECK_QUERY_CACHE_LIMIT"
},
"ttl": {
"description": "if caching of Check and ListObjects is enabled, this is the TTL of each value",
"type": "string",
"format": "duration",
"default": "10s",
"x-env-variable": "OPENFGA_CHECK_QUERY_CACHE_TTL"
}
}
}
},
"definitions": {
Expand Down
9 changes: 9 additions & 0 deletions cmd/run/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,14 @@ func bindRunFlagsFunc(flags *pflag.FlagSet) func(*cobra.Command, []string) {

util.MustBindPFlag("listObjectsMaxResults", flags.Lookup("listObjects-max-results"))
util.MustBindEnv("listObjectsMaxResults", "OPENFGA_LIST_OBJECTS_MAX_RESULTS", "OPENFGA_LISTOBJECTSMAXRESULTS")

util.MustBindPFlag("checkQueryCache.enabled", flags.Lookup("check-query-cache-enabled"))
util.MustBindEnv("checkQueryCache.enabled", "OPENFGA_CHECK_QUERY_CACHE_ENABLED")

adriantam marked this conversation as resolved.
Show resolved Hide resolved
util.MustBindPFlag("checkQueryCache.limit", flags.Lookup("check-query-cache-limit"))
util.MustBindEnv("checkQueryCache.limit", "OPENFGA_CHECK_QUERY_CACHE_LIMIT")

util.MustBindPFlag("checkQueryCache.ttl", flags.Lookup("check-query-cache-ttl"))
util.MustBindEnv("checkQueryCache.ttl", "OPENFGA_CHECK_QUERY_CACHE_TTL")
}
}
40 changes: 31 additions & 9 deletions cmd/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ func NewRunCommand() *cobra.Command {

flags.Uint32("listObjects-max-results", defaultConfig.ListObjectsMaxResults, "the maximum results to return in non-streaming ListObjects API responses. If 0, all results can be returned")

flags.Bool("check-query-cache-enabled", defaultConfig.CheckQueryCache.Enabled, "when executing Check and ListObjects requests, enables caching. This will turn Check and ListObjects responses into eventually consistent responses")
adriantam marked this conversation as resolved.
Show resolved Hide resolved

flags.Uint32("check-query-cache-limit", defaultConfig.CheckQueryCache.Limit, "if caching of Check and ListObjects calls is enabled, this is the size limit of the cache")

flags.Duration("check-query-cache-ttl", defaultConfig.CheckQueryCache.TTL, "if caching of Check and ListObjects is enabled, this is the TTL of each value")

// NOTE: if you add a new flag here, update the function below, too

cmd.PreRun = bindRunFlagsFunc(flags)
Expand Down Expand Up @@ -301,6 +307,13 @@ type MetricConfig struct {
EnableRPCHistograms bool
}

// CheckQueryCache defines configuration for caching when resolving check
type CheckQueryCache struct {
Enabled bool
Limit uint32 // (in items)
TTL time.Duration
}

type Config struct {
// If you change any of these settings, please update the documentation at https://github.com/openfga/openfga.dev/blob/main/docs/content/intro/setup-openfga.mdx

Expand Down Expand Up @@ -338,15 +351,16 @@ type Config struct {
// ResolveNodeBreadthLimit indicates how many nodes on a given level can be evaluated concurrently in a query
ResolveNodeBreadthLimit uint32

Datastore DatastoreConfig
GRPC GRPCConfig
HTTP HTTPConfig
Authn AuthnConfig
Log LogConfig
Trace TraceConfig
Playground PlaygroundConfig
Profiler ProfilerConfig
Metrics MetricConfig
Datastore DatastoreConfig
GRPC GRPCConfig
HTTP HTTPConfig
Authn AuthnConfig
Log LogConfig
Trace TraceConfig
Playground PlaygroundConfig
Profiler ProfilerConfig
Metrics MetricConfig
CheckQueryCache CheckQueryCache
}

// DefaultConfig returns the OpenFGA server default configurations.
Expand Down Expand Up @@ -410,6 +424,11 @@ func DefaultConfig() *Config {
Addr: "0.0.0.0:2112",
EnableRPCHistograms: false,
},
CheckQueryCache: CheckQueryCache{
Enabled: false,
Limit: 10000,
TTL: 10 * time.Second,
},
}
}

Expand Down Expand Up @@ -720,6 +739,9 @@ func (s *ServerContext) Run(ctx context.Context, config *Config) error {
server.WithListObjectsMaxResults(config.ListObjectsMaxResults),
adriantam marked this conversation as resolved.
Show resolved Hide resolved
server.WithMaxConcurrentReadsForListObjects(config.MaxConcurrentReadsForListObjects),
server.WithMaxConcurrentReadsForCheck(config.MaxConcurrentReadsForCheck),
server.WithCheckQueryCacheEnabled(config.CheckQueryCache.Enabled),
server.WithCheckQueryCacheLimit(config.CheckQueryCache.Limit),
server.WithCheckQueryCacheTTL(config.CheckQueryCache.TTL),
server.WithExperimentals(experimentals...),
)

Expand Down
45 changes: 45 additions & 0 deletions cmd/run/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,18 @@ func TestDefaultConfig(t *testing.T) {
val = res.Get("properties.trace.properties.serviceName.default")
require.True(t, val.Exists())
require.Equal(t, val.String(), cfg.Trace.ServiceName)

val = res.Get("properties.checkQueryCache.properties.enabled.default")
require.True(t, val.Exists())
require.Equal(t, val.Bool(), cfg.CheckQueryCache.Enabled)

val = res.Get("properties.checkQueryCache.properties.limit.default")
require.True(t, val.Exists())
require.EqualValues(t, val.Int(), cfg.CheckQueryCache.Limit)

val = res.Get("properties.checkQueryCache.properties.ttl.default")
require.True(t, val.Exists())
require.Equal(t, val.String(), cfg.CheckQueryCache.TTL.String())
}

func TestRunCommandNoConfigDefaultValues(t *testing.T) {
Expand All @@ -1067,6 +1079,9 @@ func TestRunCommandNoConfigDefaultValues(t *testing.T) {
runCmd.RunE = func(cmd *cobra.Command, _ []string) error {
require.Equal(t, "", viper.GetString(datastoreEngineFlag))
require.Equal(t, "", viper.GetString(datastoreURIFlag))
require.False(t, viper.GetBool("check-query-cache-enabled"))
require.Equal(t, uint32(0), viper.GetUint32("check-query-cache-limit"))
require.Equal(t, 0*time.Second, viper.GetDuration("check-query-cache-ttl"))
return nil
}

Expand Down Expand Up @@ -1096,6 +1111,30 @@ func TestRunCommandConfigFileValuesAreParsed(t *testing.T) {
require.Nil(t, rootCmd.Execute())
}

func TestParseConfig(t *testing.T) {
config := `checkQueryCache:
enabled: true
limit: 100
TTL: 5s
`
util.PrepareTempConfigFile(t, config)

runCmd := NewRunCommand()
runCmd.RunE = func(cmd *cobra.Command, _ []string) error {
return nil
}
rootCmd := cmd.NewRootCommand()
rootCmd.AddCommand(runCmd)
rootCmd.SetArgs([]string{"run"})
require.Nil(t, rootCmd.Execute())

cfg, err := ReadConfig()
require.NoError(t, err)
require.True(t, cfg.CheckQueryCache.Enabled)
require.Equal(t, uint32(100), cfg.CheckQueryCache.Limit)
require.Equal(t, 5*time.Second, cfg.CheckQueryCache.TTL)
}

func TestRunCommandConfigIsMerged(t *testing.T) {
config := `datastore:
engine: postgres
Expand All @@ -1104,12 +1143,18 @@ func TestRunCommandConfigIsMerged(t *testing.T) {

t.Setenv("OPENFGA_DATASTORE_URI", "postgres://postgres:PASS2@127.0.0.1:5432/postgres")
t.Setenv("OPENFGA_MAX_TYPES_PER_AUTHORIZATION_MODEL", "1")
t.Setenv("OPENFGA_CHECK_QUERY_CACHE_ENABLED", "true")
t.Setenv("OPENFGA_CHECK_QUERY_CACHE_LIMIT", "33")
t.Setenv("OPENFGA_CHECK_QUERY_CACHE_TTL", "5s")

runCmd := NewRunCommand()
runCmd.RunE = func(cmd *cobra.Command, _ []string) error {
require.Equal(t, "postgres", viper.GetString(datastoreEngineFlag))
require.Equal(t, "postgres://postgres:PASS2@127.0.0.1:5432/postgres", viper.GetString(datastoreURIFlag))
require.Equal(t, "1", viper.GetString("max-types-per-authorization-model"))
require.True(t, viper.GetBool("check-query-cache-enabled"))
require.Equal(t, uint32(33), viper.GetUint32("check-query-cache-limit"))
require.Equal(t, 5*time.Second, viper.GetDuration("check-query-cache-ttl"))
return nil
}

Expand Down
Loading
Loading