Compare commits

..

4 Commits

Author SHA1 Message Date
cuddle-please
0d3bcdf00d chore(release): 0.7.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-25 07:55:08 +00:00
c29a84d15e chore
All checks were successful
continuous-integration/drone/push Build is passing
2025-06-25 09:48:35 +02:00
01274c1364 feat: add wait 2025-06-25 09:47:34 +02:00
9c3f2cb7f7 feat: add conditional, allows adding or waiting for close 2025-06-25 09:44:45 +02:00
4 changed files with 80 additions and 5 deletions

View File

@ -6,7 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.7.2] - 2025-03-04
## [0.7.2] - 2025-06-25
### Added
- add wait
- add conditional, allows adding or waiting for close
### Fixed
- *(deps)* update rust crate async-trait to v0.1.86 (#28)
@ -22,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- *(deps)* update rust crate tokio-util to v0.7.13 (#17)
### Other
- chore
- *(deps)* update all dependencies (#29)
- *(deps)* update rust crate anyhow to v1.0.95 (#23)
- *(deps)* update all dependencies (#16)

View File

@ -4,8 +4,8 @@ version.workspace = true
description = "notmad is a life-cycle manager for long running rust operations"
license = "MIT"
repository = "https://github.com/kjuulh/mad"
author = "kjuulh"
edition = "2021"
authors = ["kjuulh"]
edition = "2024"
[dependencies]
anyhow.workspace = true

View File

@ -1,10 +1,14 @@
use futures::stream::FuturesUnordered;
use futures_util::StreamExt;
use std::{fmt::Display, sync::Arc};
use tokio::signal::unix::{signal, SignalKind};
use tokio::signal::unix::{SignalKind, signal};
use tokio_util::sync::CancellationToken;
use crate::waiter::Waiter;
mod waiter;
#[derive(thiserror::Error, Debug)]
pub enum MadError {
#[error("component failed: {0}")]
@ -70,6 +74,23 @@ impl Mad {
self
}
pub fn add_conditional(&mut self, condition: bool, component: impl IntoComponent) -> &mut Self {
if condition {
self.components.push(component.into_component());
} else {
self.components
.push(Waiter::new(component.into_component()).into_component())
}
self
}
pub fn add_wait(&mut self) -> &mut Self {
self.components.push(Waiter::default().into_component());
self
}
pub fn add_fn<F, Fut>(&mut self, f: F) -> &mut Self
where
F: Fn(CancellationToken) -> Fut + Send + Sync + 'static,
@ -100,7 +121,7 @@ impl Mad {
(Err(run), Err(close)) => {
return Err(MadError::AggregateError(AggregateError {
errors: vec![run, close],
}))
}));
}
(Ok(_), Ok(_)) => {}
(Ok(_), Err(close)) => return Err(close),

48
crates/mad/src/waiter.rs Normal file
View File

@ -0,0 +1,48 @@
use std::sync::Arc;
use async_trait::async_trait;
use tokio_util::sync::CancellationToken;
use crate::{Component, MadError};
pub struct DefaultWaiter {}
#[async_trait]
impl Component for DefaultWaiter {
async fn run(&self, _cancellation_token: CancellationToken) -> Result<(), MadError> {
panic!("should never be called");
}
}
pub struct Waiter {
comp: Arc<dyn Component + Send + Sync + 'static>,
}
impl Default for Waiter {
fn default() -> Self {
Self {
comp: Arc::new(DefaultWaiter {}),
}
}
}
impl Waiter {
pub fn new(c: Arc<dyn Component + Send + Sync + 'static>) -> Self {
Self { comp: c }
}
}
#[async_trait]
impl Component for Waiter {
fn name(&self) -> Option<String> {
match self.comp.name() {
Some(name) => Some(format!("waiter/{name}")),
None => Some("waiter".into()),
}
}
async fn run(&self, cancellation_token: CancellationToken) -> Result<(), MadError> {
cancellation_token.cancelled().await;
Ok(())
}
}