Skip to content

Commit 6fc9ffa

Browse files
committed
fix: debounce failover rechecks and refine interface
1 parent b30838f commit 6fc9ffa

4 files changed

Lines changed: 107 additions & 64 deletions

File tree

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ src-tauri/target
77
*.log
88
playwright-report
99
test-results
10+
.agents
11+
.codex
12+
.impeccable
13+
PRODUCT.md

‎src-tauri/src/core.rs‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,9 @@ impl AppCore {
598598
where
599599
F: Fn(&NodeDefinition, &HealthSummary) -> HealthSummary,
600600
{
601-
let _run = self.full_node_test_lock.lock();
602-
*self.full_node_test_result.lock() = None;
601+
let Some(_run) = self.full_node_test_lock.try_lock() else {
602+
return Ok(FailoverOutcome::Skipped);
603+
};
603604

604605
let before = self.settings()?;
605606
if !before.acceleration_enabled
@@ -608,6 +609,7 @@ impl AppCore {
608609
{
609610
return Ok(FailoverOutcome::Skipped);
610611
}
612+
*self.full_node_test_result.lock() = None;
611613
let from = self
612614
.nodes()?
613615
.into_iter()
@@ -3115,6 +3117,7 @@ mod tests {
31153117
"https://second.example/https://github.com/",
31163118
);
31173119
configure_automatic_nodes(&core, &[first.clone(), second.clone()], &first.id);
3120+
*core.full_node_test_result.lock() = Some(Err("stale result".into()));
31183121

31193122
let outcome = core
31203123
.recheck_failed_node_with(&first.id, |_, previous| HealthSummary {
@@ -3135,6 +3138,7 @@ mod tests {
31353138
to: "Second".into()
31363139
}
31373140
);
3141+
assert!(core.full_node_test_result.lock().is_none());
31383142
let settings = core.settings().unwrap();
31393143
assert_eq!(settings.current_node_id.as_deref(), Some("second"));
31403144
assert!(settings.acceleration_enabled);
@@ -3258,6 +3262,34 @@ mod tests {
32583262
);
32593263
}
32603264

3265+
#[test]
3266+
fn failed_node_recheck_skips_without_clearing_results_while_a_test_is_running() {
3267+
let directory = tempfile::tempdir().unwrap();
3268+
let core = AppCore::new(directory.path().to_path_buf()).unwrap();
3269+
let node = custom_node(
3270+
"current",
3271+
"Current",
3272+
"https://current.example/https://github.com/",
3273+
);
3274+
configure_automatic_nodes(&core, std::slice::from_ref(&node), &node.id);
3275+
*core.full_node_test_result.lock() = Some(Err("existing result".into()));
3276+
let active = core.full_node_test_lock.lock();
3277+
3278+
let outcome = core
3279+
.recheck_failed_node_with(&node.id, |_, _| {
3280+
panic!("recheck must not probe while another node test is running")
3281+
})
3282+
.unwrap();
3283+
3284+
assert_eq!(outcome, FailoverOutcome::Skipped);
3285+
assert!(core
3286+
.full_node_test_result
3287+
.lock()
3288+
.as_ref()
3289+
.is_some_and(|result| result.as_ref().unwrap_err() == "existing result"));
3290+
drop(active);
3291+
}
3292+
32613293
#[test]
32623294
fn real_git_recheck_falls_back_to_direct_when_no_node_is_usable() {
32633295
const MARKER: &str = "GITBOOST_REAL_FAILURE_RECHECK_CHILD";

0 commit comments

Comments
 (0)