Skip to main content

bge_m3_embedding_server/embedder/worker/
logging.rs

1// Copyright (c) 2026 J. Patrick Fulton
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Observability helpers for abandoned in-flight requests.
16
17use anyhow::Result;
18
19/// Emits a `WARN` if the oneshot reply receiver has been dropped while the
20/// worker was busy with `embed_*` — meaning the client (often the router's
21/// hedged race) disconnected after dispatch and the inference work is now
22/// discarded. We can't interrupt ORT `session.run()` mid-call, so this is
23/// observability only: operators can correlate `inference_ms` and `chunks`
24/// across requests to size the router's cancellation budget.
25///
26/// The reply is sent unconditionally by the caller after this returns; the
27/// channel layer will silently drop the value if the receiver is gone.
28use crate::embedder::types::EmbedStats;
29
30pub(super) fn log_if_abandoned_mid_flight<T>(
31    reply: &tokio::sync::oneshot::Sender<Result<(T, EmbedStats)>>,
32    route: &'static str,
33    worker_id: usize,
34    result: &Result<(T, EmbedStats)>,
35    inference_ms: u128,
36) {
37    if !reply.is_closed() {
38        return;
39    }
40    let (chunks, max_chunk_seq, total_token_positions) = match result {
41        Ok((_, stats)) => (
42            Some(stats.chunks),
43            Some(stats.max_chunk_seq),
44            Some(stats.total_token_positions),
45        ),
46        Err(_) => (None, None, None),
47    };
48    let inference_ms_u64 = u64::try_from(inference_ms).unwrap_or(u64::MAX);
49    tracing::warn!(
50        worker_id,
51        route,
52        inference_ms_so_far = inference_ms_u64,
53        chunks,
54        max_chunk_seq,
55        total_token_positions,
56        "request abandoned by client during inference (work discarded; \
57         ORT session.run() cannot be interrupted mid-call)"
58    );
59}