Skip to content

Commit

Permalink
improve tests and docs
Browse files Browse the repository at this point in the history
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
  • Loading branch information
aryan9600 committed Aug 5, 2023
1 parent 0d61c59 commit 599f5f8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
23 changes: 14 additions & 9 deletions kube-runtime/src/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,17 +419,24 @@ where
}
}

/// Config contains all the options that can be used to configure
/// the behavior of the contorller.
/// Accumulates all options that can be used on a [`Controller`] invocation.
#[derive(Clone, Debug, Default)]
pub struct Config {
debounce: Duration,
}

impl Config {
/// Sets the debounce period for the controller that allows for deduplication
/// of events, preventing unnecessary reconciliations. This is particularly useful
/// if the object is requeued instantly for a reconciliation by multiple streams.
/// The debounce duration used to deduplicate reconciliation requests.
///
/// When set to a non-zero duration, debouncing is enabled in the [`Scheduler`] resulting
/// in __trailing edge debouncing__ of reqonciler requests.
/// This option can help to reduce the amount of unnecessary reconciler calls
/// when using multiple controller relations, or during rapid phase transitions.
///
/// ## Warning
/// This option delays (and keeps delaying) reconcile requests for objects while
/// the object is updated. It can **permanently hide** updates from your reconciler
/// if set too high on objects that are updated frequently (like nodes).
pub fn debounce(&mut self, debounce: Duration) {
self.debounce = debounce;
}
Expand Down Expand Up @@ -1329,11 +1336,9 @@ mod tests {
let applier = applier(
|obj, _| {
Box::pin(async move {
// Try to flood the rescheduling buffer buffer by just putting it back in the queue
// almost immediately, but making sure its after the debounce time, so that the
// scheduler actuallys runs the request.
// Try to flood the rescheduling buffer buffer by just putting it back in the queue immediately
println!("reconciling {:?}", obj.metadata.name);
Ok(Action::requeue(Duration::from_millis(2)))
Ok(Action::requeue(Duration::ZERO))
})
},
|_: Arc<ConfigMap>, _: &Infallible, _| todo!(),
Expand Down
9 changes: 7 additions & 2 deletions kube-runtime/src/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ mod tests {
})
.await
.unwrap();
advance(Duration::from_secs(1)).await;
assert!(poll!(scheduler.next()).is_pending());
advance(Duration::from_secs(3)).await;
assert_eq!(scheduler.next().now_or_never().unwrap().unwrap().0, 1);
Expand All @@ -498,9 +499,9 @@ mod tests {
async fn scheduler_should_dedup_message_within_debounce_period() {
pause();

let now = Instant::now();
let mut now = Instant::now();
let (mut sched_tx, sched_rx) = mpsc::unbounded::<ScheduleRequest<SingletonMessage>>();
let mut scheduler = debounced_scheduler(sched_rx, Duration::from_secs(2));
let mut scheduler = debounced_scheduler(sched_rx, Duration::from_secs(3));

sched_tx
.send(ScheduleRequest {
Expand All @@ -512,14 +513,18 @@ mod tests {
assert!(poll!(scheduler.next()).is_pending());
advance(Duration::from_secs(1)).await;

now = Instant::now();
sched_tx
.send(ScheduleRequest {
message: SingletonMessage(2),
run_at: now,
})
.await
.unwrap();
// Check if the initial request was indeed duplicated.
advance(Duration::from_millis(2500)).await;
assert!(poll!(scheduler.next()).is_pending());

advance(Duration::from_secs(3)).await;
assert_eq!(scheduler.next().now_or_never().unwrap().unwrap().0, 2);
assert!(poll!(scheduler.next()).is_pending());
Expand Down

0 comments on commit 599f5f8

Please sign in to comment.