-
-
Notifications
You must be signed in to change notification settings - Fork 323
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
Introduce support for persistent metadata watches #1145
Conversation
The `watch` (and `watch_metadata` respectively) functions on the Api type are fallible, and watches are not recovered. Errors may happen for any reason, such as network induced errors, restarts (etcd can only cache so many resourve versions), and so on. To get around these failures, we have a `watcher()` utility in the runtime crate that manages the underlying stream in a persistent way, recovering on failure. This change introduces support for persistent metadata watches, through a `metadata_watcher` function in the same crate. Watches may be established on any type of resources, the main difference is that the returned types no longer correspond to the type of the Api. Instead, a concrete metadata type is returned. To support this with no breaking changes and to allow for more maintable code, a few utility functions and traits are introduced in the `runtime` crate. Signed-off-by: Matei David <matei@buoyant.io>
Signed-off-by: Matei David <matei@buoyant.io>
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## main #1145 +/- ##
==========================================
- Coverage 72.79% 72.56% -0.24%
==========================================
Files 66 66
Lines 5066 5085 +19
==========================================
+ Hits 3688 3690 +2
- Misses 1378 1395 +17
|
Signed-off-by: Matei David <matei@buoyant.io>
Signed-off-by: Matei David <matei@buoyant.io>
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.
I really like this as a non-breaking solution. You've kept the conventions the same, and also actually broken down large pieces of logic in the process. It is a bit more complex at bits, but the trait def and impl at the top helps alleviate that quite a bit. 👍
Left some comments on tests, and nits on msrv, names, but this is great!
Signed-off-by: Matei David <matei@buoyant.io>
Signed-off-by: Matei David <matei@buoyant.io>
Signed-off-by: Matei David <matei@buoyant.io>
Signed-off-by: Matei David <matei@buoyant.io>
Feature-wise this definitely makes sense to do. I'm not quite so sold on the |
It looks like we can get away with relatively minimal changes by introducing a wrapper around |
@nightkr suggested changes look really simple and clean, I prefer it over my approach. I think we discussed using Will start changing things around. |
Signed-off-by: Matei David <matei@buoyant.io>
Okay, made the changes, I think it's looking good. Left some questions on that gist -- did not want to clutter up the PR -- was curious about how we handle the stream since I haven't worked with Anyway, ready for a re-review whenever either or both of you get a chance. Thanks a lot for your time! |
Looks like some examples still need to be updated.
|
Signed-off-by: Matei David <matei@buoyant.io>
Signed-off-by: Matei David <matei@buoyant.io>
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 once https://github.com/kube-rs/kube/pull/1145/files#r1112598273 is resolved, thanks!
Signed-off-by: Matei David <matei@buoyant.io>
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.
Super happy that we've gotten this to the point here where the use case is now a drop-in replacement. Great work!
* Introduce support for persistent metadata watches The `watch` (and `watch_metadata` respectively) functions on the Api type are fallible, and watches are not recovered. Errors may happen for any reason, such as network induced errors, restarts (etcd can only cache so many resourve versions), and so on. To get around these failures, we have a `watcher()` utility in the runtime crate that manages the underlying stream in a persistent way, recovering on failure. This change introduces support for persistent metadata watches, through a `metadata_watcher` function in the same crate. Watches may be established on any type of resources, the main difference is that the returned types no longer correspond to the type of the Api. Instead, a concrete metadata type is returned. To support this with no breaking changes and to allow for more maintable code, a few utility functions and traits are introduced in the `runtime` crate. Signed-off-by: Matei David <matei@buoyant.io> * Run clippy Signed-off-by: Matei David <matei@buoyant.io> * Make closure arg generic Signed-off-by: Matei David <matei@buoyant.io> * Fix doc test Signed-off-by: Matei David <matei@buoyant.io> * Bump MSRV to 1.63.0 Signed-off-by: Matei David <matei@buoyant.io> * Rename AsyncFn to StepFn Signed-off-by: Matei David <matei@buoyant.io> * Add a compile-time typecheck and a meta example to dynamic watcher Signed-off-by: Matei David <matei@buoyant.io> * Rename watch_metadata to metadata_watcher and allow module rep Signed-off-by: Matei David <matei@buoyant.io> * Add trait to specialize Api calls instead of relying on closures Signed-off-by: Matei David <matei@buoyant.io> * Change meta watcher fn name in example Signed-off-by: Matei David <matei@buoyant.io> * Parse evar as 1 Signed-off-by: Matei David <matei@buoyant.io> * Refactor dynamic_watcher example Signed-off-by: Matei David <matei@buoyant.io> --------- Signed-off-by: Matei David <matei@buoyant.io>
Motivation
The
watch
(andwatch_metadata
respectively) functions on the Api type are fallible, and watches are not recovered. Errors may happen for any reason, such as network induced errors, restarts (etcd can only cache so many resource versions), and so on. To get around these failures, we have awatcher()
utility in the runtime crate that manages the underlying stream in a persistent way, recovering on failure.We should support the same type of behaviour, but for metadata-only responses. This change adds support for setting up persistent watches for metadata only, by using a similar utility (
watch_metadata
, because clippy complained aboutmetadata_watcher
).Solution
To implement this, we simply need a new function that creates a metadata specific stream. We also need to ensure that call
list_metadata
andwatch_metadata
instep_trampolined
instead oflist
andwatch
when driving the watcher.This ended up being a bit of a longer solution than I had anticipated at first. As far as the solution goes, here is what I kept in mind and what I strove to optimise for:
watcher
On Discord, we had a back and forth where we thought the best thing here would be to specialize through a trait. If we were to use indirection in
step_trampoline
, we could calllist
andwatch
on the trait, which would allow us to specialize forApi<PartialObjectMeta>
. This wasn't a huge success since we can't implement the trait forApi
twice (once forApi<K>
and once forApi<PartialObjectMeta>
).The next best thing that would allow us to keep everything the same was to try and specialize through closures. The easiest way has been to split
step_trampoline
up into smaller pieces. We duplicatestep
. Inside eachstep
function we use a factory to create two closures that will represent parts of the watcher state machine API: one to list, and one to watch.This allows us to keep most of the logic generic and special-case only a small part of the code. We introduce a new
AsyncFn
trait that allows the factories to have a nested impl return typeimpl Fn(..) -> impl Future<..>
.Original commit message
Introduce support for persistent metadata watches