fix(peer): preserve monitor backoff per root
Track the last attempted configured root separately from the last successful snapshot. A root switch clears backoff once; repeated budget failures on that same root now retain exponential delay. Test Plan: - just test - just clippy - repeated failing-root backoff regression - git diff --check
This commit is contained in:
@@ -132,9 +132,18 @@ impl PollBudget {
|
||||
struct PollBackoff {
|
||||
failures: u32,
|
||||
retry_at: Option<Instant>,
|
||||
observed_root: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl PollBackoff {
|
||||
fn observe_root(&mut self, root: &Path) {
|
||||
if self.observed_root.as_deref() == Some(root) {
|
||||
return;
|
||||
}
|
||||
self.observed_root = Some(root.to_path_buf());
|
||||
self.record_success();
|
||||
}
|
||||
|
||||
fn should_attempt(&self, now: Instant) -> bool {
|
||||
self.retry_at.is_none_or(|retry_at| now >= retry_at)
|
||||
}
|
||||
@@ -264,14 +273,8 @@ async fn poll_local_game_changes(
|
||||
previous: &mut Option<PollSnapshot>,
|
||||
backoff: &mut PollBackoff,
|
||||
) {
|
||||
let configured_game_dir = ctx.game_dir.read().await;
|
||||
if previous
|
||||
.as_ref()
|
||||
.is_some_and(|snapshot| snapshot.game_dir != *configured_game_dir)
|
||||
{
|
||||
backoff.record_success();
|
||||
}
|
||||
drop(configured_game_dir);
|
||||
let configured_game_dir = ctx.game_dir.read().await.clone();
|
||||
backoff.observe_root(&configured_game_dir);
|
||||
|
||||
let now = Instant::now();
|
||||
if !backoff.should_attempt(now) {
|
||||
@@ -733,6 +736,27 @@ mod tests {
|
||||
assert_eq!(backoff.failures, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_change_resets_backoff_only_once_until_a_snapshot_succeeds() {
|
||||
let now = Instant::now();
|
||||
let mut backoff = PollBackoff::default();
|
||||
let first_root = Path::new("/first");
|
||||
let failing_root = Path::new("/oversized");
|
||||
|
||||
backoff.observe_root(first_root);
|
||||
backoff.record_failure(now);
|
||||
backoff.observe_root(failing_root);
|
||||
assert!(backoff.should_attempt(now));
|
||||
|
||||
let delay = backoff.record_failure(now);
|
||||
backoff.observe_root(failing_root);
|
||||
assert!(
|
||||
!backoff.should_attempt(now),
|
||||
"re-observing the same failing root must preserve its backoff"
|
||||
);
|
||||
assert!(backoff.should_attempt(now + delay));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn snapshot_diff_detects_game_change_and_disappearance() {
|
||||
let temp = TempDir::new("lanspread-local-monitor-change");
|
||||
|
||||
Reference in New Issue
Block a user