hive-agent: extract turn-error recovery to fix clippy too_many_lines on handle_turn
This commit is contained in:
parent
a11f945532
commit
77e30dd1bc
1 changed files with 47 additions and 33 deletions
|
|
@ -810,6 +810,52 @@ async fn handle_turn<S: Surface>(
|
||||||
if outcome.is_ok() {
|
if outcome.is_ok() {
|
||||||
S::ack_turn(socket).await;
|
S::ack_turn(socket).await;
|
||||||
}
|
}
|
||||||
|
handle_turn_error_recovery::<S>(&outcome, bus, socket).await;
|
||||||
|
if let Some(stats) = stats {
|
||||||
|
// Fresh session this turn → mint a `sessions` row and set its id on
|
||||||
|
// the bus so this turn (and subsequent ones until the next fresh
|
||||||
|
// start) stamp `turn_stats.session_id`. Takes the one-shot flag
|
||||||
|
// `run_claude` set when it suppressed `--continue`.
|
||||||
|
if bus.take_fresh_session() {
|
||||||
|
let sid = stats.start_session(started_at, &model_at_start);
|
||||||
|
bus.set_session_id(sid);
|
||||||
|
}
|
||||||
|
let ended_at = chrono::Utc::now().timestamp();
|
||||||
|
let duration_ms = i64::try_from(started_instant.elapsed().as_millis()).unwrap_or(i64::MAX);
|
||||||
|
let (open_threads, open_reminders) = S::post_turn_counts(socket).await;
|
||||||
|
let row = serve_common::build_row(serve_common::TurnRowArgs {
|
||||||
|
started_at,
|
||||||
|
ended_at,
|
||||||
|
duration_ms,
|
||||||
|
model: model_at_start,
|
||||||
|
wake_from: from.clone(),
|
||||||
|
outcome: &outcome,
|
||||||
|
bus,
|
||||||
|
open_threads_count: open_threads,
|
||||||
|
open_reminders_count: open_reminders,
|
||||||
|
});
|
||||||
|
stats.record(&row);
|
||||||
|
}
|
||||||
|
let pending = S::inbox_unread(socket).await;
|
||||||
|
if pending > 0 {
|
||||||
|
tracing::info!(%pending, "pending messages after turn; fetching next");
|
||||||
|
}
|
||||||
|
TurnControl {
|
||||||
|
auth_failed: matches!(outcome, Err(turn::TurnError::AuthFailed)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The non-happy-path half of `handle_turn`: react to each `TurnError`
|
||||||
|
/// variant the turn could have failed with (park-and-retry on rate-limit/
|
||||||
|
/// stall/auth, requeue-for-a-fresh-turn on prompt-too-long/session-not-
|
||||||
|
/// found, notify the parent on a hard failure). Split out purely to keep
|
||||||
|
/// `handle_turn` itself under clippy's line-count lint — no behavior
|
||||||
|
/// change from when this lived inline.
|
||||||
|
async fn handle_turn_error_recovery<S: Surface>(
|
||||||
|
outcome: &turn::TurnOutcome,
|
||||||
|
bus: &Bus,
|
||||||
|
socket: &Path,
|
||||||
|
) {
|
||||||
if matches!(outcome, Err(turn::TurnError::RateLimited)) {
|
if matches!(outcome, Err(turn::TurnError::RateLimited)) {
|
||||||
let secs = turn::rate_limit_sleep_secs();
|
let secs = turn::rate_limit_sleep_secs();
|
||||||
bus.emit_status("rate_limited");
|
bus.emit_status("rate_limited");
|
||||||
|
|
@ -860,39 +906,7 @@ async fn handle_turn<S: Surface>(
|
||||||
tracing::warn!("session-not-found; requeueing message for a fresh turn");
|
tracing::warn!("session-not-found; requeueing message for a fresh turn");
|
||||||
S::requeue_inflight(socket).await;
|
S::requeue_inflight(socket).await;
|
||||||
}
|
}
|
||||||
if let Err(turn::TurnError::Failed(e)) = &outcome {
|
if let Err(turn::TurnError::Failed(e)) = outcome {
|
||||||
S::send_to_parent(socket, format_turn_failure(e)).await;
|
S::send_to_parent(socket, format_turn_failure(e)).await;
|
||||||
}
|
}
|
||||||
if let Some(stats) = stats {
|
|
||||||
// Fresh session this turn → mint a `sessions` row and set its id on
|
|
||||||
// the bus so this turn (and subsequent ones until the next fresh
|
|
||||||
// start) stamp `turn_stats.session_id`. Takes the one-shot flag
|
|
||||||
// `run_claude` set when it suppressed `--continue`.
|
|
||||||
if bus.take_fresh_session() {
|
|
||||||
let sid = stats.start_session(started_at, &model_at_start);
|
|
||||||
bus.set_session_id(sid);
|
|
||||||
}
|
|
||||||
let ended_at = chrono::Utc::now().timestamp();
|
|
||||||
let duration_ms = i64::try_from(started_instant.elapsed().as_millis()).unwrap_or(i64::MAX);
|
|
||||||
let (open_threads, open_reminders) = S::post_turn_counts(socket).await;
|
|
||||||
let row = serve_common::build_row(serve_common::TurnRowArgs {
|
|
||||||
started_at,
|
|
||||||
ended_at,
|
|
||||||
duration_ms,
|
|
||||||
model: model_at_start,
|
|
||||||
wake_from: from.clone(),
|
|
||||||
outcome: &outcome,
|
|
||||||
bus,
|
|
||||||
open_threads_count: open_threads,
|
|
||||||
open_reminders_count: open_reminders,
|
|
||||||
});
|
|
||||||
stats.record(&row);
|
|
||||||
}
|
|
||||||
let pending = S::inbox_unread(socket).await;
|
|
||||||
if pending > 0 {
|
|
||||||
tracing::info!(%pending, "pending messages after turn; fetching next");
|
|
||||||
}
|
|
||||||
TurnControl {
|
|
||||||
auth_failed: matches!(outcome, Err(turn::TurnError::AuthFailed)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue