mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 18:07:47 +08:00
feat(routing): make client disconnect behavior strategy-scoped
This commit is contained in:
@@ -822,15 +822,20 @@ where
|
||||
let started_at = Instant::now();
|
||||
let (tx, rx) = mpsc::channel::<Result<Bytes, IoError>>(1);
|
||||
let request_diagnostics = current_request_diagnostics();
|
||||
let cancel_on_disconnect = crate::request_lifecycle::cancel_on_client_disconnect();
|
||||
|
||||
tokio::spawn(async move {
|
||||
scope_request_diagnostics_with(request_diagnostics, async move {
|
||||
let bytes = standard_text_sync_heartbeat_final_bytes(
|
||||
let completion = standard_text_sync_heartbeat_final_bytes(
|
||||
client_api_format.as_str(),
|
||||
redaction_slot.as_ref(),
|
||||
execute(state, parts, trace_id, decision, plan_kind, started_at).await,
|
||||
)
|
||||
.await;
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = tx.closed(), if cancel_on_disconnect => return,
|
||||
result = execute(state, parts, trace_id, decision, plan_kind, started_at) => result,
|
||||
},
|
||||
);
|
||||
let bytes = completion.await;
|
||||
let _ = tx.send(Ok(Bytes::from(bytes))).await;
|
||||
})
|
||||
.await;
|
||||
@@ -1097,23 +1102,26 @@ fn build_openai_image_sync_heartbeat_shell_response(
|
||||
let started_at = Instant::now();
|
||||
let (tx, rx) = mpsc::channel::<Result<Bytes, IoError>>(1);
|
||||
let request_diagnostics = current_request_diagnostics();
|
||||
let cancel_on_disconnect = crate::request_lifecycle::cancel_on_client_disconnect();
|
||||
|
||||
tokio::spawn(async move {
|
||||
scope_request_diagnostics_with(request_diagnostics, async move {
|
||||
let bytes = openai_image_sync_heartbeat_final_bytes(
|
||||
execute_openai_image_sync_heartbeat_attempts(
|
||||
state,
|
||||
request_path,
|
||||
trace_id,
|
||||
decision,
|
||||
plan_kind,
|
||||
attempts,
|
||||
transfer_tracker,
|
||||
started_at,
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.await;
|
||||
let execution = execute_openai_image_sync_heartbeat_attempts(
|
||||
state,
|
||||
request_path,
|
||||
trace_id,
|
||||
decision,
|
||||
plan_kind,
|
||||
attempts,
|
||||
transfer_tracker,
|
||||
started_at,
|
||||
);
|
||||
let outcome = tokio::select! {
|
||||
biased;
|
||||
_ = tx.closed(), if cancel_on_disconnect => return,
|
||||
result = execution => result,
|
||||
};
|
||||
let bytes = openai_image_sync_heartbeat_final_bytes(outcome).await;
|
||||
let _ = tx.send(Ok(Bytes::from(bytes))).await;
|
||||
})
|
||||
.await;
|
||||
@@ -2331,6 +2339,45 @@ mod tests {
|
||||
.expect("background completion should release admission");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn standard_text_sync_heartbeat_cancels_when_routing_policy_enables_it() {
|
||||
let (started_tx, started_rx) = tokio::sync::oneshot::channel();
|
||||
let (mut release_tx, release_rx) = tokio::sync::oneshot::channel::<()>();
|
||||
let response = crate::request_lifecycle::run_request(async move {
|
||||
crate::request_lifecycle::configure_client_disconnect(
|
||||
aether_routing_core::RoutingExecutionPolicy {
|
||||
cancel_on_client_disconnect: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let (parts, _) = http::Request::builder()
|
||||
.method("POST")
|
||||
.uri("/v1/responses")
|
||||
.body(())
|
||||
.unwrap()
|
||||
.into_parts();
|
||||
build_standard_text_sync_heartbeat_shell_response(
|
||||
AppState::new().unwrap(),
|
||||
parts,
|
||||
"trace-heartbeat-disconnect".to_string(),
|
||||
test_standard_text_heartbeat_decision(),
|
||||
TEST_STANDARD_TEXT_SYNC_PLAN_KIND.to_string(),
|
||||
move |_, _, _, _, _, _| async move {
|
||||
started_tx.send(()).unwrap();
|
||||
release_rx.await.unwrap();
|
||||
Ok(LocalExecutionRequestOutcome::NoPath)
|
||||
},
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
started_rx.await.unwrap();
|
||||
drop(response);
|
||||
tokio::time::timeout(Duration::from_secs(1), release_tx.closed())
|
||||
.await
|
||||
.expect("heartbeat must drop upstream execution immediately");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn standard_text_sync_heartbeat_propagates_request_diagnostics_to_terminal_usage() {
|
||||
let (state, usage_repository) = heartbeat_usage_test_state(json!({
|
||||
|
||||
Reference in New Issue
Block a user