Skip to content

Commit 276719c

Browse files
cluxnightkr
andauthored
Add backoff handling for watcher and Controller - for #577 (#703)
* implement backoff for watcher - for #577 Signed-off-by: clux <sszynrae@gmail.com> * move magic number into strategy Signed-off-by: clux <sszynrae@gmail.com> * expose backoff from watcher and semi-propagate into controller awkward. will write a comment Signed-off-by: clux <sszynrae@gmail.com> * potential abstraction Signed-off-by: clux <sszynrae@gmail.com> * another builder layer; allow eliding ListParams Signed-off-by: clux <sszynrae@gmail.com> * forgot to add file Signed-off-by: clux <sszynrae@gmail.com> * easy parts of code review Signed-off-by: clux <sszynrae@gmail.com> * rewrite as a helper (take N) jesus this stuff is hard. Signed-off-by: clux <sszynrae@gmail.com> * rename as suggested Signed-off-by: clux <sszynrae@gmail.com> * Reimplement watcher backoff as FSM (#720) * Fix clippy warnings Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Reimplement watch backoff as FSM Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Remove useless lifetime bounds Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Silence clippy size warning Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Silence clippy properly this time around Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Split StreamBackoff into a separate utils module Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Backoff tests Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Add stream close test Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * remove backoff pin, fix docs Signed-off-by: clux <sszynrae@gmail.com> * newline Signed-off-by: clux <sszynrae@gmail.com> * Add `Backoff` wrapper that implements client-go's reset timer behaviour (#729) Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * use new reset backoff and replicate client-go reflector values Signed-off-by: clux <sszynrae@gmail.com> * fix node watcher example Signed-off-by: clux <sszynrae@gmail.com> * Use released `backoff` Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Factor out default `Backoff` Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Add note to `watcher` about backoff Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Added backoff to Controller Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Changelog Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Revert `Observer` for now Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * The clippyman comes for us all, eventually And we must all pay our due respects, or pay the price. Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * Fix build warnings Signed-off-by: Teo Klestrup Röijezon <teo@nullable.se> * remove backoff_watch Signed-off-by: clux <sszynrae@gmail.com> * doc tweaks Signed-off-by: clux <sszynrae@gmail.com> * sentence Signed-off-by: clux <sszynrae@gmail.com> * upgrading backoff is not actually breaking Signed-off-by: clux <sszynrae@gmail.com> Co-authored-by: Teo Klestrup Röijezon <teo.roijezon@stackable.de> Co-authored-by: Teo Klestrup Röijezon <teo@nullable.se>
1 parent 155859b commit 276719c

22 files changed

Lines changed: 372 additions & 35 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ UNRELEASED
33
===================
44
* see https://github.com/kube-rs/kube-rs/compare/0.65.0...master
55
* Added `DeleteParams::background()`, `DeleteParams::foreground()`, `DeleteParams::orphan()` constructors - [#747](https://github.com/kube-rs/kube-rs/issues/747)
6+
* Introduced `StreamBackoff` mechanism for backing off watchers - #703
7+
* BREAKING: `Controller` now uses `backoff` for trigger watches by default, use `Controller::trigger_backoff` to override
68

79
0.65.0 / 2021-12-10
810
===================

examples/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ tower = { version = "0.4.6", features = ["limit"] }
5252
tower-http = { version = "0.2.0", features = ["trace", "decompression-gzip"] }
5353
hyper = { version = "0.14.13", features = ["client", "http1", "stream", "tcp"] }
5454
thiserror = "1.0.29"
55+
backoff = "0.4.0"
5556

5657
[[example]]
5758
name = "configmapgen_controller"

examples/dynamic_jsonpath.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use jsonpath_lib;
21
use k8s_openapi::api::core::v1::Pod;
32
use kube::{
43
api::{Api, ListParams},

examples/dynamic_pod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ async fn main() -> anyhow::Result<()> {
1818
}
1919
#[derive(Clone, Deserialize, Debug)]
2020
struct ContainerSimple {
21+
#[allow(dead_code)]
2122
image: String,
2223
}
2324
type PodSimple = Object<PodSpecSimple, NotUsed>;

examples/dynamic_watcher.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ async fn main() -> anyhow::Result<()> {
2828
let api = Api::<DynamicObject>::all_with(client, &ar);
2929

3030
// Fully compatible with kube-runtime
31-
let watcher = watcher(api, ListParams::default());
32-
try_flatten_applied(watcher)
31+
try_flatten_applied(watcher(api, ListParams::default()))
3332
.try_for_each(|p| async move {
3433
log::info!("Applied: {}", p.name());
3534
Ok(())

examples/event_watcher.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[macro_use] extern crate log;
2-
use futures::{StreamExt, TryStreamExt};
2+
use futures::{pin_mut, TryStreamExt};
33
use k8s_openapi::api::core::v1::Event;
44
use kube::{
55
api::{Api, ListParams},
@@ -16,8 +16,9 @@ async fn main() -> anyhow::Result<()> {
1616
let events: Api<Event> = Api::all(client);
1717
let lp = ListParams::default();
1818

19-
let mut ew = try_flatten_applied(watcher(events, lp)).boxed();
19+
let ew = try_flatten_applied(watcher(events, lp));
2020

21+
pin_mut!(ew);
2122
while let Some(event) = ew.try_next().await? {
2223
handle_event(event)?;
2324
}

examples/job_api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use k8s_openapi::api::batch::v1::Job;
44
use serde_json::json;
55

66
use kube::{
7-
api::{Api, DeleteParams, ListParams, PostParams, PropagationPolicy, ResourceExt, WatchEvent},
7+
api::{Api, DeleteParams, ListParams, PostParams, ResourceExt, WatchEvent},
88
Client,
99
};
1010

examples/node_watcher.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#[macro_use] extern crate log;
2-
use futures::{StreamExt, TryStreamExt};
2+
use backoff::ExponentialBackoff;
3+
use futures::{pin_mut, TryStreamExt};
34
use k8s_openapi::api::core::v1::{Event, Node};
45
use kube::{
56
api::{Api, ListParams, ResourceExt},
6-
runtime::{utils::try_flatten_applied, watcher},
7+
runtime::{
8+
utils::{try_flatten_applied, StreamBackoff},
9+
watcher,
10+
},
711
Client,
812
};
913

@@ -15,10 +19,13 @@ async fn main() -> anyhow::Result<()> {
1519
let events: Api<Event> = Api::all(client.clone());
1620
let nodes: Api<Node> = Api::all(client.clone());
1721

18-
let lp = ListParams::default().labels("beta.kubernetes.io/os=linux");
22+
let obs = try_flatten_applied(StreamBackoff::new(
23+
watcher(nodes, ListParams::default().labels("beta.kubernetes.io/os=linux")),
24+
ExponentialBackoff::default(),
25+
));
1926

20-
let mut apply_stream = try_flatten_applied(watcher(nodes, lp)).boxed();
21-
while let Some(n) = apply_stream.try_next().await? {
27+
pin_mut!(obs);
28+
while let Some(n) = obs.try_next().await? {
2229
check_for_node_failures(&events, n).await?;
2330
}
2431
Ok(())

examples/pod_watcher.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ async fn main() -> anyhow::Result<()> {
1313
let client = Client::try_default().await?;
1414
let namespace = std::env::var("NAMESPACE").unwrap_or_else(|_| "default".into());
1515
let api = Api::<Pod>::namespaced(client, &namespace);
16-
let watcher = watcher(api, ListParams::default());
17-
try_flatten_applied(watcher)
16+
17+
try_flatten_applied(watcher(api, ListParams::default()))
1818
.try_for_each(|p| async move {
1919
log::debug!("Applied: {}", p.name());
2020
if let Some(unready_reason) = pod_unready(&p) {

kube-client/src/discovery/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct Discovery {
6363
/// Builds an internal map of its cache
6464
impl Discovery {
6565
/// Construct a caching api discovery client
66+
#[must_use]
6667
pub fn new(client: Client) -> Self {
6768
let groups = HashMap::new();
6869
let mode = DiscoveryMode::Block(vec![]);

0 commit comments

Comments
 (0)