hive-agent: only wake the boot-announce todo when it actually changed
This commit is contained in:
parent
f33a1ed660
commit
bc11b85e07
1 changed files with 41 additions and 1 deletions
|
|
@ -50,7 +50,8 @@ pub fn announce(label: &str, todos: &Todos, wake: &Notify) {
|
||||||
still in your window."
|
still in your window."
|
||||||
);
|
);
|
||||||
match todos.upsert(SUBSYSTEM, Some(KEY), &summary, None, true) {
|
match todos.upsert(SUBSYSTEM, Some(KEY), &summary, None, true) {
|
||||||
Ok(_) => wake.notify_one(),
|
Ok((_, true)) => wake.notify_one(),
|
||||||
|
Ok((_, false)) => {}
|
||||||
Err(e) => tracing::warn!(error = ?e, "boot_announce: todo upsert failed"),
|
Err(e) => tracing::warn!(error = ?e, "boot_announce: todo upsert failed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +60,16 @@ pub fn announce(label: &str, todos: &Todos, wake: &Notify) {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
/// Drains any pending permit so the next check starts from "no wake
|
||||||
|
/// armed" — `notify_one` coalesces multiple calls into a single
|
||||||
|
/// stored permit, so an un-drained leftover from a prior step would
|
||||||
|
/// make this step's check pass regardless of whether `announce` wove
|
||||||
|
/// in a fresh one.
|
||||||
|
fn wake_fired(wake: &Notify) -> bool {
|
||||||
|
use futures_util::FutureExt as _;
|
||||||
|
wake.notified().now_or_never().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn two_boots_without_an_ack_leave_one_row() {
|
fn two_boots_without_an_ack_leave_one_row() {
|
||||||
let dir = tempfile::tempdir().expect("tempdir");
|
let dir = tempfile::tempdir().expect("tempdir");
|
||||||
|
|
@ -87,4 +98,33 @@ mod tests {
|
||||||
assert_eq!(rows.len(), 1);
|
assert_eq!(rows.len(), 1);
|
||||||
assert_eq!(rows[0].id, id);
|
assert_eq!(rows[0].id, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn only_a_changed_upsert_wakes() {
|
||||||
|
let dir = tempfile::tempdir().expect("tempdir");
|
||||||
|
let todos = Todos::open(&dir.path().join("state.sqlite")).expect("open");
|
||||||
|
let wake = Notify::new();
|
||||||
|
|
||||||
|
// First boot: fresh row, must wake.
|
||||||
|
announce("a", &todos, &wake);
|
||||||
|
assert!(wake_fired(&wake), "first boot wakes");
|
||||||
|
|
||||||
|
// Second boot before any ack: same row, unchanged summary — must
|
||||||
|
// NOT wake. This is the restart-storm case: a boot while the
|
||||||
|
// notice is still pending costs nothing extra.
|
||||||
|
announce("a", &todos, &wake);
|
||||||
|
assert!(
|
||||||
|
!wake_fired(&wake),
|
||||||
|
"repeat boot with the row still open must not wake"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ack it, then boot again: the row reopens — must wake again.
|
||||||
|
let id = todos.list(Some(SUBSYSTEM)).expect("list")[0].id;
|
||||||
|
todos.mark_done(id).expect("mark_done");
|
||||||
|
announce("a", &todos, &wake);
|
||||||
|
assert!(
|
||||||
|
wake_fired(&wake),
|
||||||
|
"boot after an ack reopens the row and wakes"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue