Fix/issue 817 idle timeout log level (#824)
* fix(transport): downgrade idle timeout log from error to debug Idle keep-alive timeout is normal zombie-session cleanup, not a transport failure. Route it through a dedicated WorkerQuitReason::IdleTimeout variant. Log it at debug level instead of treating it as a fatal error. Remove the unused LocalSessionWorkerError::KeepAliveTimeout variant. Closes #817 * fix(session): tolerate dead worker in close_session Swallow SessionServiceTerminated in close_session when the worker has already exited. This prevents a spurious ERROR log during the post-exit cleanup path in spawn_session_worker. * fix(transport): address PR review feedback - deprecate KeepAliveTimeout - harden tests
This commit is contained in:
parent
014fb2e6cd
commit
2f8d3b7355
2 changed files with 269 additions and 6 deletions
|
|
@ -66,9 +66,16 @@ impl SessionManager for LocalSessionManager {
|
|||
Ok(response)
|
||||
}
|
||||
async fn close_session(&self, id: &SessionId) -> Result<(), Self::Error> {
|
||||
let mut sessions = self.sessions.write().await;
|
||||
if let Some(handle) = sessions.remove(id) {
|
||||
handle.close().await?;
|
||||
let handle = {
|
||||
let mut sessions = self.sessions.write().await;
|
||||
sessions.remove(id)
|
||||
};
|
||||
if let Some(handle) = handle {
|
||||
match handle.close().await {
|
||||
// Worker already exited — nothing left to clean up.
|
||||
Ok(()) | Err(SessionError::SessionServiceTerminated) => {}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -928,6 +935,7 @@ pub enum LocalSessionWorkerError {
|
|||
FailToSendInitializeRequest(SessionError),
|
||||
#[error("fail to handle message: {0}")]
|
||||
FailToHandleMessage(SessionError),
|
||||
#[deprecated(note = "idle timeout now surfaces as WorkerQuitReason::IdleTimeout")]
|
||||
#[error("keep alive timeout after {}ms", _0.as_millis())]
|
||||
KeepAliveTimeout(Duration),
|
||||
#[error("init timeout after {}ms", _0.as_millis())]
|
||||
|
|
@ -1021,7 +1029,7 @@ impl Worker for LocalSessionWorker {
|
|||
return Err(WorkerQuitReason::Cancelled)
|
||||
}
|
||||
_ = keep_alive_timeout => {
|
||||
return Err(WorkerQuitReason::fatal(LocalSessionWorkerError::KeepAliveTimeout(keep_alive), "poll next session event"))
|
||||
return Err(WorkerQuitReason::IdleTimeout(keep_alive))
|
||||
}
|
||||
};
|
||||
match event {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::borrow::Cow;
|
||||
use std::{borrow::Cow, time::Duration};
|
||||
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{Instrument, Level};
|
||||
|
|
@ -22,6 +22,8 @@ pub enum WorkerQuitReason<E> {
|
|||
TransportClosed,
|
||||
#[error("Handler terminated")]
|
||||
HandlerTerminated,
|
||||
#[error("Worker idle timeout after {}ms", _0.as_millis())]
|
||||
IdleTimeout(Duration),
|
||||
}
|
||||
|
||||
impl<E: std::error::Error + Send + 'static> WorkerQuitReason<E> {
|
||||
|
|
@ -122,7 +124,8 @@ impl<W: Worker> WorkerTransport<W> {
|
|||
.inspect_err(|e| match e {
|
||||
WorkerQuitReason::Cancelled
|
||||
| WorkerQuitReason::TransportClosed
|
||||
| WorkerQuitReason::HandlerTerminated => {
|
||||
| WorkerQuitReason::HandlerTerminated
|
||||
| WorkerQuitReason::IdleTimeout(_) => {
|
||||
tracing::debug!("worker quit with reason: {:?}", e);
|
||||
}
|
||||
WorkerQuitReason::Join(e) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue