hive-matrix-mcp: test the retry path and the once-only todo clear
The startup todo wipe runs once in main, before any sync loop, so a secondary that comes up later cannot clear the todos the running accounts' sweeps already deduped. Nothing tested that. main now reads HIVE_AGENT_SOCKET once at startup and hands the path to wake::clear_all_todos, the only way left to wipe the whole set; send_todo_clear clears one key only. bring_up_account is split into restore_account (everything that talks to the network) and the synchronous account_sync_loop, and the retry path restores with the former and builds the loop itself. Neither the loop nor the retry path is given the socket. The new test runs a late secondary's retry and its sync loop against a listener standing in for the harness socket, after startup's wipe, and asserts the harness saw exactly one wipe. It pins that seam, not every place in restore_account a wipe could be added.
This commit is contained in:
parent
bd6009ff33
commit
739c35757a
4 changed files with 140 additions and 72 deletions
|
|
@ -23,7 +23,8 @@ const TODO_SOCKET_RETRY: Retry = Retry::None;
|
|||
/// go — distinct from the host-served control socket used by `send_wake`.
|
||||
/// `None` when unset/empty, in which case todo sends are a best-effort
|
||||
/// no-op (a standalone daemon without the harness socket).
|
||||
fn agent_socket() -> Option<std::path::PathBuf> {
|
||||
#[must_use]
|
||||
pub fn agent_socket() -> Option<std::path::PathBuf> {
|
||||
std::env::var_os("HIVE_AGENT_SOCKET")
|
||||
.filter(|v| !v.is_empty())
|
||||
.map(std::path::PathBuf::from)
|
||||
|
|
@ -52,26 +53,40 @@ pub async fn send_todo_upsert(key: &str, summary: impl AsRef<str>) -> Result<()>
|
|||
notify(&socket, &payload, TODO_SOCKET_RETRY).await
|
||||
}
|
||||
|
||||
/// Clear matrix-subsystem todos on the harness's in-agent socket. `key =
|
||||
/// Some(room)` clears one room's todo (it was read); `all = true` wipes the
|
||||
/// whole matrix set (cancel-and-recreate on daemon restart). Best-effort:
|
||||
/// a no-op when `HIVE_AGENT_SOCKET` isn't configured.
|
||||
/// Clear the matrix-subsystem todo `key` on the harness's in-agent socket
|
||||
/// (its room was read, or its invite resolved). Best-effort: a no-op when
|
||||
/// `HIVE_AGENT_SOCKET` isn't configured.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error on socket connect failure, serialisation failure,
|
||||
/// or I/O error writing to or reading from the socket.
|
||||
pub async fn send_todo_clear(key: Option<&str>, all: bool) -> Result<()> {
|
||||
pub async fn send_todo_clear(key: &str) -> Result<()> {
|
||||
let Some(socket) = agent_socket() else {
|
||||
return Ok(());
|
||||
};
|
||||
send_clear(&socket, Some(key), false).await
|
||||
}
|
||||
|
||||
/// Wipe the whole matrix todo set on `socket` (cancel-and-recreate on daemon
|
||||
/// start). Takes the socket instead of reading `HIVE_AGENT_SOCKET`, so only
|
||||
/// code handed the path can wipe the set.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// As [`send_todo_clear`].
|
||||
pub async fn clear_all_todos(socket: &std::path::Path) -> Result<()> {
|
||||
send_clear(socket, None, true).await
|
||||
}
|
||||
|
||||
async fn send_clear(socket: &std::path::Path, key: Option<&str>, all: bool) -> Result<()> {
|
||||
let payload = serde_json::json!({
|
||||
"cmd": "clear_todo",
|
||||
"subsystem": "matrix",
|
||||
"key": key,
|
||||
"all": all,
|
||||
});
|
||||
notify(&socket, &payload, TODO_SOCKET_RETRY).await
|
||||
notify(socket, &payload, TODO_SOCKET_RETRY).await
|
||||
}
|
||||
|
||||
/// Format a wake-message body from a list of per-room unread summaries.
|
||||
|
|
|
|||
Loading…
Reference in a new issue