-
Notifications
You must be signed in to change notification settings - Fork 26
[FSSDK-8838] feat(odp-cache): Adds support for odp cache. #365
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
Conversation
* Adds support for odp options in config.yaml
jaeopt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Some suggestions to reuse go-sdk cache. Let's discuss options.
config/config.go
Outdated
| EventsRequestTimeout time.Duration `json:"eventsRequestTimeout"` | ||
| EventsFlushInterval time.Duration `json:"eventsFlushInterval"` | ||
| Disable bool `json:"disable"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| EventsRequestTimeout time.Duration `json:"eventsRequestTimeout"` | |
| EventsFlushInterval time.Duration `json:"eventsFlushInterval"` | |
| Disable bool `json:"disable"` | |
| Disable bool `json:"disable"` | |
| EventsRequestTimeout time.Duration `json:"eventsRequestTimeout"` | |
| EventsFlushInterval time.Duration `json:"eventsFlushInterval"` |
plugins/odpcache/README.md
Outdated
| @@ -0,0 +1,64 @@ | |||
| # ODP Cache | |||
| Use a ODP Cache to persist segments and ensure they are sticky. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Use a ODP Cache to persist segments and ensure they are sticky. | |
| Use a ODP Cache to cache user segments fetched from the ODP server. |
| ) | ||
|
|
||
| // InMemoryCache represents the in-memory implementation of Cache interface | ||
| type InMemoryCache struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not clear about the value of providing an option to use this in-memory cache. It looks like instantiating the same URLCache implemented in go-sdk. Can't we use the default one already in go-sdk?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are now using this as default odp cache with both timeout and size as arguments. Following is the default configuration:
odp:
## Disable odp
disable: false
## Timeout in seconds after which event requests will timeout.
eventsRequestTimeout: 10s
## Flush interval in seconds for odp events
eventsFlushInterval: 1s
## Timeout in seconds after which segment requests will timeout.
segmentsRequestTimeout: 10s
## This will override all other settings
segmentsCache:
default: "in-memory"
services:
in-memory:
size: 10000
timeout: 600 # seconds
# redis:
# host: "localhost:6379"
# password: ""
# database: 0
# timeout: 0 # seconds
| } | ||
|
|
||
| // Check if JSON string was set using OPTIMIZELY_CLIENT_ODP_SEGMENTSCACHE environment variable | ||
| if odpSegmentsCache := v.GetStringMap("client.odp.segmentsCache"); odpSegmentsCache != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering why we need this support for odpCache only? What about other odp config like "client.odp"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No specific reason, its just something that we did for ups aswell.
config.yaml
Outdated
| segmentsCacheTimeout: 600s | ||
| ## Timeout in seconds after which segment requests will timeout. | ||
| segmentsRequestTimeout: 10s | ||
| ## This will override all other settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we be more specific about overriding? CacheSize and CacheTimeout will be overriden. Others like "disable" etc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted this comment as segmentsCacheTimeout and segmentsCacheSize no longer exist outside of the scope of in-memory cache.
config.yaml
Outdated
| segmentsRequestTimeout: 10s | ||
| ## This will override all other settings | ||
| segmentsCache: | ||
| default: "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this empty default imply? Will agent use go-sdk native URLCache with segmentCacheSize and segmentsCacheTimeout? Or is it cache disabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as per the new implementation, empty default simply means that go-sdk will use its default LRU cache with default timeout and size
config.yaml
Outdated
| # in-memory: | ||
| # size: 0 | ||
| # timeout: 0 # seconds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this in-memory cache the same as one in go-sdk (implemented and active by default)?
If so, we can use size and timeout for its config (segmentsCacheSize and segmentsCacheTimeout above can be removed).
What about "in-memory" as default for "default: in-memory"? So, they'll use go-sdk cache unless override with redis etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this default config make sense?
disable: false
eventsRequestTimeout: 10s
eventsFlushInterval: 1s
segmentsRequestTimeout: 10s
segmentsCache:
default: "in-memory"
services:
in-memory:
size: 10000
timeout: 600s
# redis:
# host:
#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the suggestion, went with the same approach.
| # size: 0 | ||
| # timeout: 0 # seconds | ||
| # redis: | ||
| # host: "localhost:6379" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we need to control redis timeout as well? We can reuse segmentsCacheTimeout but it may be confusing since we do not use segmentsCacheSize for redis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added timeout to redis aswell.
| func init() { | ||
| redisCacheCreator := func() cache.Cache { | ||
| return &RedisCache{ | ||
| Expiration: 0 * time.Second, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need timeout control for redis cache. Can't we add timeout to config?
jaeopt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All changes look good! A few small fixes suggested.
cmd/optimizely/testdata/default.yaml
Outdated
| redis: | ||
| host: "localhost:6379" | ||
| password: "" | ||
| timeout: 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5s ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5s was possible if the key was at the root and viper was unmarshalling it. In this case we are unmarshalling it at runtime using native json library which does not support converting 5s to time duration.
config.yaml
Outdated
| # timeout: 0 # seconds | ||
| in-memory: | ||
| size: 10000 | ||
| timeout: 600 # seconds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
600s ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above.
config.yaml
Outdated
| # host: "localhost:6379" | ||
| # password: "" | ||
| # database: 0 | ||
| # timeout: 0 # seconds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
600s default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above.
config.yaml
Outdated
| segmentsCacheTimeout: 600s | ||
| ## Timeout in seconds after which segment requests will timeout. | ||
| segmentsRequestTimeout: 10s | ||
| ## This will override all other settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No overriding any more. This line should be removed.
jaeopt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! A few minor fixes suggested.
plugins/odpcache/README.md
Outdated
| in-memory: | ||
| ## 0 means cache will be disabled | ||
| size: 0 | ||
| ## timeout after which least recently used records will be deleted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ## timeout after which least recently used records will be deleted | |
| ## timeout after which the cached item will become invalid. |
| ## configure optional ODP Cache | ||
| odp: | ||
| segmentsCache: | ||
| default: "in-memory" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be better if default "default" is clarified. If no segmentsCache is defined (or no default is defined), we will use the default in-memory with default size and timeout?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement is true, if none provided then sdk uses its own in-memory with default values: https://github.com/optimizely/go-sdk/blob/master/pkg/odp/segment/segment_manager.go#L87
|
|
||
| switch value := unmarshalledJSON.(type) { | ||
| case float64: | ||
| duration.Duration = time.Duration(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we accept number without unit? What is the default unit for this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes we do, default unit is nanosecond by golang.
jaeopt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Summary
in-memoryandredis.in-memorywill use the builtin LRU cache with user providedsizeandtimeout.sizeandtimeout.Out of Box ODP Cache Usage
ODPCache, update theconfig.yamlas shown below:ODPCache, update theconfig.yamlas shown below:Custom ODPCache Implementation
To implement a custom odp cache, followings steps need to be taken:
cache.Cacheinterface inplugins/odpcache/services.initmethod inside your ODPCache file as shown below:config.yamlfile with yourODPCacheconfig as shown below:If a user has created multiple
ODPCacheservices and wants to override thedefaultODPCachefor a specificsdkKey, they can do so by providing theODPCachename in the request HeaderX-Optimizely-ODP-Cache-Name.Whenever a request is made with a unique
sdkKey, The agent node handling that request creates and caches a newODPCache. To keep theODPCachetype consistent among all nodes in a cluster, it is recommended to send the request HeaderX-Optimizely-ODP-Cache-Namein every request made.Tests
Ticket
FSSDK-8838