hive-agent: add debug logging around todo upsert/clear/mark-done
diagnostic instrumentation for #2678 (phantom 'you have todos' wakes after clearing bash-task todos). logs subsystem/key/id/changed on UpsertTodo, subsystem/key/all/count on ClearTodo, id/count on MarkTodoDone, and a marker when the serve loop actually consumes a todo_wake notification. no behavior change - RUST_LOG=debug only.
This commit is contained in:
parent
9f82dc4e7d
commit
2dcbb78b40
2 changed files with 66 additions and 44 deletions
|
|
@ -585,7 +585,10 @@ async fn serve_loop<S: Surface>(
|
||||||
}
|
}
|
||||||
} {
|
} {
|
||||||
RecvOutcome::Message(first) => first,
|
RecvOutcome::Message(first) => first,
|
||||||
RecvOutcome::LocalTodo => synthetic_todo_message(),
|
RecvOutcome::LocalTodo => {
|
||||||
|
tracing::debug!("todo wake consumed, sending synthetic todo message");
|
||||||
|
synthetic_todo_message()
|
||||||
|
}
|
||||||
RecvOutcome::Empty => {
|
RecvOutcome::Empty => {
|
||||||
// Idle: no message this poll. Service a queued operator
|
// Idle: no message this poll. Service a queued operator
|
||||||
// `/compact` here so it runs even when no turn is driving
|
// `/compact` here so it runs even when no turn is driving
|
||||||
|
|
|
||||||
|
|
@ -165,49 +165,10 @@ fn dispatch(
|
||||||
bus: &Bus,
|
bus: &Bus,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
match req {
|
match req {
|
||||||
Request::UpsertTodo {
|
Request::UpsertTodo { .. }
|
||||||
subsystem,
|
| Request::ClearTodo { .. }
|
||||||
key,
|
| Request::ListTodos { .. }
|
||||||
summary,
|
| Request::MarkTodoDone { .. } => dispatch_todo(req, store, wake),
|
||||||
source,
|
|
||||||
} => match store.upsert(&subsystem, key.as_deref(), &summary, source.as_deref()) {
|
|
||||||
Ok((_, changed)) => {
|
|
||||||
if changed {
|
|
||||||
wake.notify_one();
|
|
||||||
}
|
|
||||||
Response::Ok
|
|
||||||
}
|
|
||||||
Err(e) => err(&e),
|
|
||||||
},
|
|
||||||
Request::ClearTodo {
|
|
||||||
subsystem,
|
|
||||||
key,
|
|
||||||
all,
|
|
||||||
} => {
|
|
||||||
let result = if all {
|
|
||||||
store.clear_subsystem(&subsystem)
|
|
||||||
} else {
|
|
||||||
store.clear(&subsystem, key.as_deref())
|
|
||||||
};
|
|
||||||
match result {
|
|
||||||
Ok(count) => Response::Acked {
|
|
||||||
count: u64::try_from(count).unwrap_or(0),
|
|
||||||
},
|
|
||||||
Err(e) => err(&e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Request::ListTodos { subsystem } => match store.list(subsystem.as_deref()) {
|
|
||||||
Ok(todos) => Response::LooseEnds {
|
|
||||||
loose_ends: todos.into_iter().map(to_loose_end).collect(),
|
|
||||||
},
|
|
||||||
Err(e) => err(&e),
|
|
||||||
},
|
|
||||||
Request::MarkTodoDone { id } => match store.mark_done(id) {
|
|
||||||
Ok(count) => Response::Acked {
|
|
||||||
count: u64::try_from(count).unwrap_or(0),
|
|
||||||
},
|
|
||||||
Err(e) => err(&e),
|
|
||||||
},
|
|
||||||
Request::StoreReminder {
|
Request::StoreReminder {
|
||||||
message,
|
message,
|
||||||
timing,
|
timing,
|
||||||
|
|
@ -260,6 +221,64 @@ fn dispatch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Todo-family requests (loose-ends v2). `req` is guaranteed by [`dispatch`]
|
||||||
|
/// to be one of the four todo variants; any other variant is a caller bug.
|
||||||
|
fn dispatch_todo(req: Request, store: &Todos, wake: &Notify) -> Response {
|
||||||
|
match req {
|
||||||
|
Request::UpsertTodo {
|
||||||
|
subsystem,
|
||||||
|
key,
|
||||||
|
summary,
|
||||||
|
source,
|
||||||
|
} => match store.upsert(&subsystem, key.as_deref(), &summary, source.as_deref()) {
|
||||||
|
Ok((id, changed)) => {
|
||||||
|
tracing::debug!(subsystem = %subsystem, key = ?key, id, changed, "todo upsert");
|
||||||
|
if changed {
|
||||||
|
wake.notify_one();
|
||||||
|
}
|
||||||
|
Response::Ok
|
||||||
|
}
|
||||||
|
Err(e) => err(&e),
|
||||||
|
},
|
||||||
|
Request::ClearTodo {
|
||||||
|
subsystem,
|
||||||
|
key,
|
||||||
|
all,
|
||||||
|
} => {
|
||||||
|
let result = if all {
|
||||||
|
store.clear_subsystem(&subsystem)
|
||||||
|
} else {
|
||||||
|
store.clear(&subsystem, key.as_deref())
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(count) => {
|
||||||
|
tracing::debug!(subsystem = %subsystem, key = ?key, all, count, "todo clear");
|
||||||
|
Response::Acked {
|
||||||
|
count: u64::try_from(count).unwrap_or(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => err(&e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Request::ListTodos { subsystem } => match store.list(subsystem.as_deref()) {
|
||||||
|
Ok(todos) => Response::LooseEnds {
|
||||||
|
loose_ends: todos.into_iter().map(to_loose_end).collect(),
|
||||||
|
},
|
||||||
|
Err(e) => err(&e),
|
||||||
|
},
|
||||||
|
Request::MarkTodoDone { id } => match store.mark_done(id) {
|
||||||
|
Ok(count) => {
|
||||||
|
tracing::debug!(id, count, "todo mark-done");
|
||||||
|
Response::Acked {
|
||||||
|
count: u64::try_from(count).unwrap_or(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => err(&e),
|
||||||
|
},
|
||||||
|
_ => unreachable!("dispatch only routes todo variants here"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `Request::Compact` handler: gate on context usage, then queue the same
|
/// `Request::Compact` handler: gate on context usage, then queue the same
|
||||||
/// deferred `compact_pending` flag the operator's `/compact` button sets.
|
/// deferred `compact_pending` flag the operator's `/compact` button sets.
|
||||||
/// Mirrors `hive-agent::web_ui::actions::post_compact` but reachable from
|
/// Mirrors `hive-agent::web_ui::actions::post_compact` but reachable from
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue