-
Notifications
You must be signed in to change notification settings - Fork 3
chore: Add support for persistent store contract tests. #502
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
base: main
Are you sure you want to change the base?
Changes from all commits
2edfc8d
baeb833
eb918dd
d960e6f
14b2e22
d09ca12
b9a13e4
9a95f3e
bdcb385
8d4e39c
e5bf095
cc44864
6cf1a3c
3fe6eb3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently this SDK doesn't support read-write mode. It supports a purely lazy system for use with daemon mode.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With FDv2 support we will want to standardize this with the FDv2 behavior. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| persistent data store/redis/read-write/initializes store when data received | ||
| persistent data store/redis/read-write/applies updates to store | ||
| persistent data store/redis/read-write/data source updates respect versioning | ||
| persistent data store/redis/read-write/data source deletions respect versioning | ||
| persistent data store/redis/read-write/cache mode infinite/does not cache flag miss | ||
| persistent data store/redis/read-write/cache mode infinite/sdk reflects data source updates even with cache | ||
| persistent data store/redis/read-write/cache mode infinite/ignores direct database modifications | ||
| persistent data store/redis/read-write/cache mode infinite/ignores dropped flags | ||
| persistent data store/redis/read-write/cache mode ttl/does not cache flag miss | ||
| persistent data store/redis/read-write/cache mode ttl/sdk reflects data source updates even with cache | ||
| persistent data store/redis/read-write/cache mode ttl/ignores direct database modifications | ||
| persistent data store/redis/read-write/cache mode ttl/ignores dropped flags |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| #include "client_impl.hpp" | ||
|
|
||
| #include "all_flags_state/all_flags_state_builder.hpp" | ||
|
|
@@ -186,11 +186,19 @@ | |
| std::unordered_map<Client::FlagKey, Value> result; | ||
|
|
||
| if (!Initialized()) { | ||
| LD_LOG(logger_, LogLevel::kWarn) | ||
| << "AllFlagsState() called before client has finished " | ||
| "initializing. Data source not available. Returning empty state"; | ||
| if (data_system_->CanEvaluateWhenNotInitialized()) { | ||
| LD_LOG(logger_, LogLevel::kWarn) | ||
| << "AllFlagsState() called before LaunchDarkly client " | ||
| "initialization completed; using last known values " | ||
| "from data store"; | ||
| } else { | ||
| LD_LOG(logger_, LogLevel::kWarn) | ||
| << "AllFlagsState() called before client has finished " | ||
| "initializing. Data source not available. Returning " | ||
| "empty state"; | ||
|
|
||
| return {}; | ||
| return {}; | ||
| } | ||
| } | ||
|
|
||
| AllFlagsStateBuilder builder{options}; | ||
|
|
@@ -418,7 +426,16 @@ | |
| std::optional<enum EvaluationReason::ErrorKind> ClientImpl::PreEvaluationChecks( | ||
| Context const& context) const { | ||
| if (!Initialized()) { | ||
| return EvaluationReason::ErrorKind::kClientNotReady; | ||
| if (data_system_->CanEvaluateWhenNotInitialized()) { | ||
| LD_LOG(logger_, LogLevel::kWarn) | ||
| << "Evaluation called before LaunchDarkly client " | ||
| "initialization completed; using last known values " | ||
| "from data store. The $inited key was not found in " | ||
| "the store; typically a Relay Proxy or other SDK " | ||
| "should set this key."; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Warning logged on every evaluation in lazy loadMedium Severity In Additional Locations (1)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is consistent with other implementations. @keelerm84 Relay does write $inited, correct? |
||
| } else { | ||
| return EvaluationReason::ErrorKind::kClientNotReady; | ||
| } | ||
| } | ||
| if (!context.Valid()) { | ||
| return EvaluationReason::ErrorKind::kUserNotSpecified; | ||
|
|
||


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.
TTL value likely treated as wrong time unit
High Severity
The
CacheRefreshAPI acceptsstd::chrono::milliseconds, and the LaunchDarkly SDK contract test harness protocol sends thettlvalue in milliseconds. However, the code wraps the rawttlinteger instd::chrono::seconds, which implicitly converts to milliseconds by multiplying by 1000. This makes the effective cache TTL 1000× larger than intended (e.g., a harness-sent value of 30000 ms becomes 30,000 seconds instead of 30 seconds). The data model comment also incorrectly states the unit is seconds. The value likely needs to be wrapped instd::chrono::millisecondsinstead.Additional Locations (1)
contract-tests/data-model/include/data_model/data_model.hpp#L154-L155There 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.
ttl(number, optional): If the cache mode isttl, this value will be the time-to-live for cache entries in seconds.