-
Notifications
You must be signed in to change notification settings - Fork 214
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: Etag version #3248
feat: Etag version #3248
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3248 +/- ##
==========================================
+ Coverage 64.08% 64.12% +0.03%
==========================================
Files 166 168 +2
Lines 13217 13393 +176
==========================================
+ Hits 8470 8588 +118
- Misses 4091 4147 +56
- Partials 656 658 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
|
It would be nice to have an ETag per namespace. This way, if someone uses a single instance of Flipt for different environments or teams, they won't impact each other. For relational databases, we could use/update For object storage, it would be ideal to use the ETag provided by the storage system and avoid extra fetching during pooling as well. wdyt @markphelps ? |
Great idea @erka ! I might suggest we add a new column to the namespaces table instead of relying on updated_at since it has existing meaning. But I love the idea of scoping it to the namespace which means we don't need a new table. Will implement today.
Yes maybe once I update the interface to return the value for when any data under a namespace changes then you could add support for the object backends ? Then we can have each of the storage backends implement this interface |
@markphelps we're gonna need it to use for OFREP endpoints, but it should track not only the namespace as a whole but each flag too! |
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
} | ||
|
||
// HandleNoBodyResponse is a response modifier that does not write a body if the response is a 204 No Content or 304 Not Modified. | ||
func HandleNoBodyResponse(next http.Handler) http.Handler { |
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 is required because grpc gateway will always call Write
on the responseWriter, even if the status code is a 204
or 304
, and the Go stdlib will return the error: Failed to write response: http: request method or response status code does not allow body
which we don't want to log as errors in our logs
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Co-authored-by: Roman Dmytrenko <rdmytrenko@gmail.com>
@thepabloaguilar im not sure tracking it at the flag level would work since changes outside of the flag could also affect evaluation. for example if you have a flag that has a rule using a segment. any change to that segment would affect evaluation for that flag, but since it wouldn't change the flag itself then the etag wouldn't change. if that makes sense |
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 good. Are you doing the other stores in subsequent PRs?
yah right now they will just not support etags since they will always return an empty string and the logic states to no set an empty etag, so should be backward compatible. but will implement those next |
related flipt-io#3248 Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com>
related flipt-io#3248 Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com>
* feat: support etag for declarative stores related #3248 Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com> * address PR feedback Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com> * implement etag for object store Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com> --------- Signed-off-by: Roman Dmytrenko <rdmytrenko@gmail.com>
supersedes: #3240
This takes a different approach to calculating a stable etag for the
/evaluation/v1/internal/data
API (supports client-side eval)Since we can't depend on the ordering of the JSON being consistent between requests (discussed in #3240 ), we use a different way to track if any state has been mutated to calculate a stable etag.
For each mutation in the store layer we update a version value (for SQL backends) in the db by setting the current date/time that the data was mutated in that namespace.
We still need to implement this for the non-relational stores, for example the OCI and Git backends can simply return the latest reference. We'll have to also implement this for the object stores. There we could have the store hash the data that it has in memory for a stable reference.
The pros of this approach are that we have full control over when we say that the data has changes from Flipt's perspective, and we can guarantee it is consistent
TODO