Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c886d3fa6 | ||
|
|
2dcbb78b40 |
2 changed files with 80 additions and 35 deletions
|
|
@ -585,7 +585,10 @@ async fn serve_loop<S: Surface>(
|
|||
}
|
||||
} {
|
||||
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 => {
|
||||
// Idle: no message this poll. Service a queued operator
|
||||
// `/compact` here so it runs even when no turn is driving
|
||||
|
|
|
|||
|
|
@ -170,44 +170,21 @@ fn dispatch(
|
|||
key,
|
||||
summary,
|
||||
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),
|
||||
},
|
||||
} => upsert_todo(
|
||||
store,
|
||||
wake,
|
||||
&subsystem,
|
||||
key.as_deref(),
|
||||
&summary,
|
||||
source.as_deref(),
|
||||
),
|
||||
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),
|
||||
},
|
||||
} => clear_todo(store, &subsystem, key.as_deref(), all),
|
||||
Request::ListTodos { subsystem } => list_todos(store, subsystem.as_deref()),
|
||||
Request::MarkTodoDone { id } => mark_todo_done(store, id),
|
||||
Request::StoreReminder {
|
||||
message,
|
||||
timing,
|
||||
|
|
@ -260,6 +237,71 @@ fn dispatch(
|
|||
}
|
||||
}
|
||||
|
||||
/// `UpsertTodo` handler: writes/refreshes a todo row, logs the outcome, and
|
||||
/// fires `wake` on a new-or-changed upsert so the serve loop runs a turn.
|
||||
fn upsert_todo(
|
||||
store: &Todos,
|
||||
wake: &Notify,
|
||||
subsystem: &str,
|
||||
key: Option<&str>,
|
||||
summary: &str,
|
||||
source: Option<&str>,
|
||||
) -> Response {
|
||||
match store.upsert(subsystem, key, summary, source) {
|
||||
Ok((id, changed)) => {
|
||||
tracing::debug!(%subsystem, ?key, id, changed, "todo upsert");
|
||||
if changed {
|
||||
wake.notify_one();
|
||||
}
|
||||
Response::Ok
|
||||
}
|
||||
Err(e) => err(&e),
|
||||
}
|
||||
}
|
||||
|
||||
/// `ClearTodo` handler: drops one keyed todo, or every todo in `subsystem`
|
||||
/// when `all` is set.
|
||||
fn clear_todo(store: &Todos, subsystem: &str, key: Option<&str>, all: bool) -> Response {
|
||||
let result = if all {
|
||||
store.clear_subsystem(subsystem)
|
||||
} else {
|
||||
store.clear(subsystem, key)
|
||||
};
|
||||
match result {
|
||||
Ok(count) => {
|
||||
tracing::debug!(%subsystem, ?key, all, count, "todo clear");
|
||||
Response::Acked {
|
||||
count: u64::try_from(count).unwrap_or(0),
|
||||
}
|
||||
}
|
||||
Err(e) => err(&e),
|
||||
}
|
||||
}
|
||||
|
||||
/// `ListTodos` handler: read-only, so no debug logging — not relevant to
|
||||
/// diagnosing wake behaviour.
|
||||
fn list_todos(store: &Todos, subsystem: Option<&str>) -> Response {
|
||||
match store.list(subsystem) {
|
||||
Ok(todos) => Response::LooseEnds {
|
||||
loose_ends: todos.into_iter().map(to_loose_end).collect(),
|
||||
},
|
||||
Err(e) => err(&e),
|
||||
}
|
||||
}
|
||||
|
||||
/// `MarkTodoDone` handler: marks a single todo done by id.
|
||||
fn mark_todo_done(store: &Todos, id: i64) -> Response {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
/// `Request::Compact` handler: gate on context usage, then queue the same
|
||||
/// deferred `compact_pending` flag the operator's `/compact` button sets.
|
||||
/// Mirrors `hive-agent::web_ui::actions::post_compact` but reachable from
|
||||
|
|
|
|||
Loading…
Reference in a new issue