diff --git a/src/dispatching/dispatcher.rs b/src/dispatching/dispatcher.rs index 763c2c2e..88c3aa1b 100644 --- a/src/dispatching/dispatcher.rs +++ b/src/dispatching/dispatcher.rs @@ -1,5 +1,5 @@ use std::{ - fmt::Debug, + fmt::{self, Debug}, sync::{ atomic::{AtomicU8, Ordering}, Arc, @@ -458,6 +458,19 @@ where } } +/// This error is returned from [`ShutdownToken::shutdown`] when trying to +/// shutdown idle dispatcher. +#[derive(Debug)] +pub struct IdleShutdownError; + +impl fmt::Display for IdleShutdownError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Dispatcher was idle and as such couldn't be shut down") + } +} + +impl std::error::Error for IdleShutdownError {} + /// A token which can be used to shutdown dispatcher. #[derive(Clone)] pub struct ShutdownToken { @@ -471,7 +484,7 @@ impl ShutdownToken { /// Returns error if this dispather is idle at the moment. /// /// If you don't need to wait for shutdown, returned future can be ignored. - pub fn shutdown(&self) -> Result<impl Future<Output = ()> + '_, ()> { + pub fn shutdown(&self) -> Result<impl Future<Output = ()> + '_, IdleShutdownError> { shutdown_inner(&self.dispatcher_state) .map(|()| async move { self.shutdown_notify_back.notified().await }) } @@ -543,14 +556,14 @@ fn shutdown_check_timeout_for<E>(update_listener: &impl UpdateListener<E>) -> Du shutdown_check_timeout.checked_add(MIN_SHUTDOWN_CHECK_TIMEOUT).unwrap_or(shutdown_check_timeout) } -fn shutdown_inner(state: &DispatcherState) -> Result<(), ShutdownError> { +fn shutdown_inner(state: &DispatcherState) -> Result<(), IdleShutdownError> { use ShutdownState::*; let res = state.compare_exchange(Running, ShuttingDown); match res { Ok(_) | Err(ShuttingDown) => Ok(()), - Err(Idle) => Err(ShutdownError::Idle), + Err(Idle) => Err(IdleShutdownError), Err(Running) => unreachable!(), } } diff --git a/src/dispatching/mod.rs b/src/dispatching/mod.rs index 1d68bd41..9936de96 100644 --- a/src/dispatching/mod.rs +++ b/src/dispatching/mod.rs @@ -56,7 +56,7 @@ mod dispatcher_handler; mod dispatcher_handler_rx_ext; mod update_with_cx; -pub use dispatcher::{Dispatcher, ShutdownError, ShutdownToken}; +pub use dispatcher::{Dispatcher, IdleShutdownError, ShutdownToken}; pub use dispatcher_handler::DispatcherHandler; pub use dispatcher_handler_rx_ext::DispatcherHandlerRxExt; use tokio::sync::mpsc::UnboundedReceiver;