pub trait TradingService:
Send
+ Sync
+ 'static {
// Required methods
fn name(&self) -> &str;
fn run<'life0, 'async_trait>(
&'life0 self,
cancel: CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
// Provided method
fn restart_policy(&self) -> RestartPolicy { ... }
}Expand description
A long-running task managed by the crate::Supervisor.
§Cancellation contract
Implementations must select on cancel.cancelled() in their main loop.
A service that doesn’t respond to cancellation will hang the whole
shutdown process until the supervisor’s shutdown timeout fires.
§Interior mutability
run takes &self, so services wrapped in Arc work naturally. Mutable
state (counters, connection handles, etc.) should use atomics, Mutex,
or RwLock. This is required anyway by the Send + Sync + 'static bound.
§Example
A counter service that ticks every second until cancelled. Note the
tokio::select! pattern that interleaves real work with the
cancellation watch.
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
use async_trait::async_trait;
use rustrade_supervisor::{RestartPolicy, TradingService};
use tokio_util::sync::CancellationToken;
struct CounterService {
ticks: AtomicU64,
}
#[async_trait]
impl TradingService for CounterService {
fn name(&self) -> &str { "counter" }
fn restart_policy(&self) -> RestartPolicy { RestartPolicy::OnFailure }
async fn run(&self, cancel: CancellationToken) -> anyhow::Result<()> {
let mut tick = tokio::time::interval(Duration::from_secs(1));
loop {
tokio::select! {
_ = cancel.cancelled() => return Ok(()),
_ = tick.tick() => {
self.ticks.fetch_add(1, Ordering::Relaxed);
}
}
}
}
}Required Methods§
Provided Methods§
Sourcefn restart_policy(&self) -> RestartPolicy
fn restart_policy(&self) -> RestartPolicy
When should the supervisor restart this service on exit?
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".