BREAKING: name() -> info() and removed async_trait
Some checks failed
continuous-integration/drone/push Build encountered an error
Some checks failed
continuous-integration/drone/push Build encountered an error
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
use notmad::ComponentInfo;
|
||||
use rand::Rng;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::Level;
|
||||
|
||||
struct WaitServer {}
|
||||
impl notmad::Component for WaitServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("WaitServer".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"WaitServer".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//! - Graceful shutdown with cancellation tokens
|
||||
//! - Concurrent component execution
|
||||
|
||||
use notmad::{Component, Mad, MadError};
|
||||
use notmad::{Component, ComponentInfo, Mad, MadError};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use tokio::time::{Duration, interval};
|
||||
@@ -21,8 +21,8 @@ struct WebServer {
|
||||
}
|
||||
|
||||
impl Component for WebServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("web-server-{}", self.port))
|
||||
fn info(&self) -> ComponentInfo {
|
||||
format!("web-server-{}", self.port).into()
|
||||
}
|
||||
|
||||
async fn setup(&self) -> Result<(), MadError> {
|
||||
@@ -80,8 +80,8 @@ struct JobProcessor {
|
||||
}
|
||||
|
||||
impl Component for JobProcessor {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("job-processor-{}", self.queue_name))
|
||||
fn info(&self) -> ComponentInfo {
|
||||
format!("job-processor-{}", self.queue_name).into()
|
||||
}
|
||||
|
||||
async fn setup(&self) -> Result<(), MadError> {
|
||||
@@ -137,8 +137,8 @@ struct HealthChecker {
|
||||
}
|
||||
|
||||
impl Component for HealthChecker {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("health-checker".to_string())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"health-checker".into()
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), MadError> {
|
||||
@@ -178,8 +178,8 @@ struct FailingComponent {
|
||||
}
|
||||
|
||||
impl Component for FailingComponent {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("failing-component".to_string())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"failing-component".into()
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), MadError> {
|
||||
@@ -205,8 +205,8 @@ impl Component for FailingComponent {
|
||||
struct DebugComponent;
|
||||
|
||||
impl Component for DebugComponent {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("debug-component".to_string())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"debug-component".into()
|
||||
}
|
||||
|
||||
async fn run(&self, cancel: CancellationToken) -> Result<(), MadError> {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use notmad::ComponentInfo;
|
||||
use rand::Rng;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::Level;
|
||||
|
||||
struct ErrorServer {}
|
||||
impl notmad::Component for ErrorServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("ErrorServer".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"ErrorServer".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use notmad::ComponentInfo;
|
||||
use rand::Rng;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::Level;
|
||||
|
||||
struct WaitServer {}
|
||||
impl notmad::Component for WaitServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("WaitServer".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"WaitServer".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! This example shows how to run a web server, queue processor, and
|
||||
//! scheduled task together, with graceful shutdown on Ctrl+C.
|
||||
|
||||
use notmad::{Component, Mad, MadError};
|
||||
use notmad::{Component, ComponentInfo, Mad, MadError};
|
||||
use tokio::time::{Duration, interval};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
@@ -16,20 +16,20 @@ struct WebServer {
|
||||
}
|
||||
|
||||
impl Component for WebServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("WebServer:{}", self.port))
|
||||
fn info(&self) -> ComponentInfo {
|
||||
format!("WebServer:{}", self.port).into()
|
||||
}
|
||||
|
||||
async fn setup(&self) -> Result<(), MadError> {
|
||||
println!("[{}] Binding to port...", self.name().unwrap());
|
||||
println!("[{}] Binding to port...", self.info());
|
||||
// Simulate server setup time
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
println!("[{}] Ready to accept connections", self.name().unwrap());
|
||||
println!("[{}] Ready to accept connections", self.info());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), MadError> {
|
||||
println!("[{}] Server started", self.name().unwrap());
|
||||
println!("[{}] Server started", self.info());
|
||||
|
||||
// Simulate handling requests until shutdown
|
||||
let mut request_id = 0;
|
||||
@@ -38,12 +38,12 @@ impl Component for WebServer {
|
||||
while !cancellation.is_cancelled() {
|
||||
tokio::select! {
|
||||
_ = cancellation.cancelled() => {
|
||||
println!("[{}] Shutdown signal received", self.name().unwrap());
|
||||
println!("[{}] Shutdown signal received", self.info());
|
||||
break;
|
||||
}
|
||||
_ = interval.tick() => {
|
||||
request_id += 1;
|
||||
println!("[{}] Handling request #{}", self.name().unwrap(), request_id);
|
||||
println!("[{}] Handling request #{}", self.info(), request_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,10 +52,10 @@ impl Component for WebServer {
|
||||
}
|
||||
|
||||
async fn close(&self) -> Result<(), MadError> {
|
||||
println!("[{}] Closing connections...", self.name().unwrap());
|
||||
println!("[{}] Closing connections...", self.info());
|
||||
// Simulate graceful connection drain
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
println!("[{}] Server stopped", self.name().unwrap());
|
||||
println!("[{}] Server stopped", self.info());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -69,12 +69,12 @@ struct QueueProcessor {
|
||||
}
|
||||
|
||||
impl Component for QueueProcessor {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("QueueProcessor:{}", self.queue_name))
|
||||
fn info(&self) -> ComponentInfo {
|
||||
format!("QueueProcessor:{}", self.queue_name).into()
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), MadError> {
|
||||
println!("[{}] Started processing", self.name().unwrap());
|
||||
println!("[{}] Started processing", self.info());
|
||||
|
||||
let mut message_count = 0;
|
||||
|
||||
@@ -83,19 +83,19 @@ impl Component for QueueProcessor {
|
||||
// Simulate waiting for and processing a message
|
||||
tokio::select! {
|
||||
_ = cancellation.cancelled() => {
|
||||
println!("[{}] Stopping message processing", self.name().unwrap());
|
||||
println!("[{}] Stopping message processing", self.info());
|
||||
break;
|
||||
}
|
||||
_ = tokio::time::sleep(Duration::from_secs(1)) => {
|
||||
message_count += 1;
|
||||
println!("[{}] Processed message #{}", self.name().unwrap(), message_count);
|
||||
println!("[{}] Processed message #{}", self.info(), message_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
"[{}] Processed {} messages total",
|
||||
self.name().unwrap(),
|
||||
self.info(),
|
||||
message_count
|
||||
);
|
||||
Ok(())
|
||||
@@ -114,14 +114,14 @@ struct ScheduledTask {
|
||||
}
|
||||
|
||||
impl Component for ScheduledTask {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("ScheduledTask:{}", self.task_name))
|
||||
fn info(&self) -> ComponentInfo {
|
||||
format!("ScheduledTask:{}", self.task_name).into()
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), MadError> {
|
||||
println!(
|
||||
"[{}] Scheduled to run every {} seconds",
|
||||
self.name().unwrap(),
|
||||
self.info(),
|
||||
self.interval_secs
|
||||
);
|
||||
|
||||
@@ -131,17 +131,17 @@ impl Component for ScheduledTask {
|
||||
while !cancellation.is_cancelled() {
|
||||
tokio::select! {
|
||||
_ = cancellation.cancelled() => {
|
||||
println!("[{}] Scheduler stopping", self.name().unwrap());
|
||||
println!("[{}] Scheduler stopping", self.info());
|
||||
break;
|
||||
}
|
||||
_ = interval.tick() => {
|
||||
run_count += 1;
|
||||
println!("[{}] Executing run #{}", self.name().unwrap(), run_count);
|
||||
println!("[{}] Executing run #{}", self.info(), run_count);
|
||||
|
||||
// Simulate task execution
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
|
||||
println!("[{}] Run #{} completed", self.name().unwrap(), run_count);
|
||||
println!("[{}] Run #{} completed", self.info(), run_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use notmad::ComponentInfo;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
struct NestedErrorComponent {
|
||||
@@ -5,8 +6,8 @@ struct NestedErrorComponent {
|
||||
}
|
||||
|
||||
impl notmad::Component for NestedErrorComponent {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(self.name.clone())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
self.name.clone().into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
@@ -27,8 +28,8 @@ impl notmad::Component for NestedErrorComponent {
|
||||
struct AnotherFailingComponent;
|
||||
|
||||
impl notmad::Component for AnotherFailingComponent {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("another-component".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"another-component".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use notmad::ComponentInfo;
|
||||
use rand::Rng;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::Level;
|
||||
|
||||
struct WaitServer {}
|
||||
impl notmad::Component for WaitServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("WaitServer".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"WaitServer".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
@@ -22,8 +23,8 @@ impl notmad::Component for WaitServer {
|
||||
|
||||
struct RespectCancel {}
|
||||
impl notmad::Component for RespectCancel {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("RespectCancel".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"RespectCancel".into()
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
@@ -36,8 +37,8 @@ impl notmad::Component for RespectCancel {
|
||||
|
||||
struct NeverStopServer {}
|
||||
impl notmad::Component for NeverStopServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("NeverStopServer".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"NeverStopServer".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
|
||||
@@ -1,42 +1,21 @@
|
||||
//! # MAD - Lifecycle Manager for Rust Applications
|
||||
//!
|
||||
//! MAD is a robust lifecycle manager designed for long-running Rust operations. It provides
|
||||
//! a simple, composable way to manage multiple concurrent services within your application,
|
||||
//! handling graceful startup and shutdown automatically.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! MAD helps you build applications composed of multiple long-running components that need
|
||||
//! to be orchestrated together. It handles:
|
||||
//!
|
||||
//! - **Concurrent execution** of multiple components
|
||||
//! - **Graceful shutdown** with cancellation tokens
|
||||
//! - **Error aggregation** from multiple components
|
||||
//! - **Lifecycle management** with setup, run, and close phases
|
||||
//! A simple lifecycle manager for long-running Rust applications. Run multiple services
|
||||
//! concurrently with graceful shutdown handling.
|
||||
//!
|
||||
//! ## Quick Start
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use notmad::{Component, Mad};
|
||||
//! use async_trait::async_trait;
|
||||
//! use tokio_util::sync::CancellationToken;
|
||||
//!
|
||||
//! struct MyService {
|
||||
//! name: String,
|
||||
//! }
|
||||
//! struct MyService;
|
||||
//!
|
||||
//! #[async_trait]
|
||||
//! impl Component for MyService {
|
||||
//! fn name(&self) -> Option<String> {
|
||||
//! Some(self.name.clone())
|
||||
//! }
|
||||
//!
|
||||
//! async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
//! // Your service logic here
|
||||
//! while !cancellation.is_cancelled() {
|
||||
//! // Do work...
|
||||
//! tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
//! }
|
||||
//! async fn run(&self, cancel: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
//! println!("Running...");
|
||||
//! cancel.cancelled().await;
|
||||
//! println!("Stopped");
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! }
|
||||
@@ -44,36 +23,20 @@
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> anyhow::Result<()> {
|
||||
//! Mad::builder()
|
||||
//! .add(MyService { name: "service-1".into() })
|
||||
//! .add(MyService { name: "service-2".into() })
|
||||
//! .add(MyService)
|
||||
//! .run()
|
||||
//! .await?;
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Component Lifecycle
|
||||
//! ## Features
|
||||
//!
|
||||
//! Components go through three phases:
|
||||
//!
|
||||
//! 1. **Setup**: Optional initialization phase before components start running
|
||||
//! 2. **Run**: Main execution phase where components perform their work
|
||||
//! 3. **Close**: Optional cleanup phase after components stop
|
||||
//!
|
||||
//! ## Error Handling
|
||||
//!
|
||||
//! MAD provides comprehensive error handling through [`MadError`], which can:
|
||||
//! - Wrap errors from individual components
|
||||
//! - Aggregate multiple errors when several components fail
|
||||
//! - Automatically convert from `anyhow::Error`
|
||||
//!
|
||||
//! ## Shutdown Behavior
|
||||
//!
|
||||
//! MAD handles shutdown gracefully:
|
||||
//! - Responds to SIGTERM and Ctrl+C signals
|
||||
//! - Propagates cancellation tokens to all components
|
||||
//! - Waits for components to finish cleanup
|
||||
//! - Configurable cancellation timeout
|
||||
//! - Run multiple components concurrently
|
||||
//! - Graceful shutdown with cancellation tokens
|
||||
//! - Optional lifecycle hooks: `setup()`, `run()`, `close()`
|
||||
//! - Automatic error aggregation
|
||||
//! - SIGTERM and Ctrl+C signal handling
|
||||
|
||||
use futures::stream::FuturesUnordered;
|
||||
use futures_util::StreamExt;
|
||||
@@ -205,12 +168,10 @@ impl Display for AggregateError {
|
||||
///
|
||||
/// ```rust
|
||||
/// use notmad::{Component, Mad};
|
||||
/// use async_trait::async_trait;
|
||||
/// use tokio_util::sync::CancellationToken;
|
||||
///
|
||||
/// struct MyComponent;
|
||||
///
|
||||
/// #[async_trait]
|
||||
/// impl Component for MyComponent {
|
||||
/// async fn run(&self, _cancel: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
/// Ok(())
|
||||
@@ -270,10 +231,8 @@ impl Mad {
|
||||
///
|
||||
/// ```rust
|
||||
/// use notmad::{Component, Mad};
|
||||
/// # use async_trait::async_trait;
|
||||
/// # use tokio_util::sync::CancellationToken;
|
||||
/// # struct MyService;
|
||||
/// # #[async_trait]
|
||||
/// # impl Component for MyService {
|
||||
/// # async fn run(&self, _: CancellationToken) -> Result<(), notmad::MadError> { Ok(()) }
|
||||
/// # }
|
||||
@@ -303,10 +262,8 @@ impl Mad {
|
||||
/// ```rust
|
||||
/// use notmad::Mad;
|
||||
/// # use notmad::Component;
|
||||
/// # use async_trait::async_trait;
|
||||
/// # use tokio_util::sync::CancellationToken;
|
||||
/// # struct DebugService;
|
||||
/// # #[async_trait]
|
||||
/// # impl Component for DebugService {
|
||||
/// # async fn run(&self, _: CancellationToken) -> Result<(), notmad::MadError> { Ok(()) }
|
||||
/// # }
|
||||
@@ -469,7 +426,7 @@ impl Mad {
|
||||
tracing::debug!("setting up components");
|
||||
|
||||
for comp in &self.components {
|
||||
tracing::trace!(component = &comp.name(), "mad setting up");
|
||||
tracing::trace!(component = %comp.info(), "mad setting up");
|
||||
|
||||
match comp.setup().await {
|
||||
Ok(_) | Err(MadError::SetupNotDefined) => {}
|
||||
@@ -499,15 +456,15 @@ impl Mad {
|
||||
channels.push(error_rx);
|
||||
|
||||
tokio::spawn(async move {
|
||||
let name = comp.name().clone();
|
||||
let info = comp.info().clone();
|
||||
|
||||
tracing::debug!(component = name, "mad running");
|
||||
tracing::debug!(component = %info, "mad running");
|
||||
|
||||
let handle = tokio::spawn(async move { comp.run(job_cancellation).await });
|
||||
|
||||
tokio::select! {
|
||||
_ = cancellation_token.cancelled() => {
|
||||
error_tx.send(CompletionResult { res: Ok(()) , name }).await
|
||||
error_tx.send(CompletionResult { res: Ok(()) , name: info.name }).await
|
||||
}
|
||||
res = handle => {
|
||||
let res = match res {
|
||||
@@ -529,7 +486,7 @@ impl Mad {
|
||||
};
|
||||
|
||||
|
||||
error_tx.send(CompletionResult { res , name }).await
|
||||
error_tx.send(CompletionResult { res , name: info.name }).await
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -606,7 +563,7 @@ impl Mad {
|
||||
tracing::debug!("closing components");
|
||||
|
||||
for comp in &self.components {
|
||||
tracing::trace!(component = &comp.name(), "mad closing");
|
||||
tracing::trace!(component = %comp.info(), "mad closing");
|
||||
match comp.close().await {
|
||||
Ok(_) | Err(MadError::CloseNotDefined) => {}
|
||||
Err(e) => return Err(e),
|
||||
@@ -624,6 +581,46 @@ async fn signal_unix_terminate() {
|
||||
sigterm.recv().await;
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct ComponentInfo {
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
impl Display for ComponentInfo {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(
|
||||
self.name
|
||||
.as_ref()
|
||||
.map(|n| n.as_str())
|
||||
.unwrap_or_else(|| "unknown"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentInfo {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn with_name(&mut self, name: impl Into<String>) -> &mut Self {
|
||||
self.name = Some(name.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for ComponentInfo {
|
||||
fn from(value: String) -> Self {
|
||||
Self { name: Some(value) }
|
||||
}
|
||||
}
|
||||
impl From<&str> for ComponentInfo {
|
||||
fn from(value: &str) -> Self {
|
||||
Self {
|
||||
name: Some(value.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for implementing MAD components.
|
||||
///
|
||||
/// Components represent individual services or tasks that run as part
|
||||
@@ -633,18 +630,16 @@ async fn signal_unix_terminate() {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use notmad::{Component, MadError};
|
||||
/// use async_trait::async_trait;
|
||||
/// use notmad::{Component, ComponentInfo, MadError};
|
||||
/// use tokio_util::sync::CancellationToken;
|
||||
///
|
||||
/// struct DatabaseConnection {
|
||||
/// url: String,
|
||||
/// }
|
||||
///
|
||||
/// #[async_trait]
|
||||
/// impl Component for DatabaseConnection {
|
||||
/// fn name(&self) -> Option<String> {
|
||||
/// Some("database".to_string())
|
||||
/// fn info(&self) -> ComponentInfo {
|
||||
/// "database".into()
|
||||
/// }
|
||||
///
|
||||
/// async fn setup(&self) -> Result<(), MadError> {
|
||||
@@ -675,8 +670,8 @@ pub trait Component: Send + Sync + 'static {
|
||||
/// # Default
|
||||
///
|
||||
/// Returns `None` if not overridden.
|
||||
fn name(&self) -> Option<String> {
|
||||
None
|
||||
fn info(&self) -> ComponentInfo {
|
||||
ComponentInfo::default()
|
||||
}
|
||||
|
||||
/// Optional setup phase called before the component starts running.
|
||||
@@ -743,7 +738,7 @@ pub trait Component: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
trait AsyncComponent: Send + Sync + 'static {
|
||||
fn name_async(&self) -> Option<String>;
|
||||
fn info_async(&self) -> ComponentInfo;
|
||||
|
||||
fn setup_async(&self) -> Pin<Box<dyn Future<Output = Result<(), MadError>> + Send + '_>>;
|
||||
|
||||
@@ -757,8 +752,8 @@ trait AsyncComponent: Send + Sync + 'static {
|
||||
|
||||
impl<E: Component> AsyncComponent for E {
|
||||
#[inline(always)]
|
||||
fn name_async(&self) -> Option<String> {
|
||||
self.name()
|
||||
fn info_async(&self) -> ComponentInfo {
|
||||
self.info()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -787,8 +782,8 @@ pub struct SharedComponent {
|
||||
|
||||
impl SharedComponent {
|
||||
#[inline(always)]
|
||||
pub fn name(&self) -> Option<String> {
|
||||
self.component.name_async()
|
||||
pub fn info(&self) -> ComponentInfo {
|
||||
self.component.info_async()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -817,12 +812,10 @@ impl SharedComponent {
|
||||
///
|
||||
/// ```rust
|
||||
/// use notmad::{Component, IntoComponent, Mad};
|
||||
/// # use async_trait::async_trait;
|
||||
/// # use tokio_util::sync::CancellationToken;
|
||||
///
|
||||
/// struct MyService;
|
||||
///
|
||||
/// # #[async_trait]
|
||||
/// # impl Component for MyService {
|
||||
/// # async fn run(&self, _: CancellationToken) -> Result<(), notmad::MadError> { Ok(()) }
|
||||
/// # }
|
||||
@@ -974,8 +967,8 @@ mod tests {
|
||||
struct FailingComponent;
|
||||
|
||||
impl Component for FailingComponent {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("test-component".to_string())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"test-component".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancel: CancellationToken) -> Result<(), MadError> {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::{Component, IntoComponent, MadError, SharedComponent};
|
||||
use crate::{Component, ComponentInfo, IntoComponent, MadError, SharedComponent};
|
||||
|
||||
/// A default waiter component that panics if run.
|
||||
///
|
||||
@@ -60,10 +60,10 @@ impl Component for Waiter {
|
||||
///
|
||||
/// If the wrapped component has a name, it will be "waiter/{name}".
|
||||
/// Otherwise, returns "waiter".
|
||||
fn name(&self) -> Option<String> {
|
||||
match self.comp.name() {
|
||||
Some(name) => Some(format!("waiter/{name}")),
|
||||
None => Some("waiter".into()),
|
||||
fn info(&self) -> ComponentInfo {
|
||||
match &self.comp.info().name {
|
||||
Some(name) => format!("waiter/{name}").into(),
|
||||
None => "waiter".into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use notmad::{Component, Mad, MadError};
|
||||
use notmad::{Component, ComponentInfo, Mad, MadError};
|
||||
use rand::Rng;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@@ -9,8 +9,8 @@ use tracing_test::traced_test;
|
||||
struct NeverEndingRun {}
|
||||
|
||||
impl Component for NeverEndingRun {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("NeverEndingRun".into())
|
||||
fn info(&self) -> ComponentInfo {
|
||||
"NeverEndingRun".into()
|
||||
}
|
||||
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
|
||||
Reference in New Issue
Block a user