Files
MetaCrate/crates/libremetaverse/src/repeat.rs
Chili Palmer c9a1170a27
Some checks failed
API and SemVer surface / api-surface (push) Failing after 1m34s
Native code generation / deterministic (push) Has been cancelled
Concurrency and resource soak audit / soak (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
performance evidence / audit (push) Has been cancelled
First release candidate / non-fuzz-release-gate (push) Has been cancelled
Release platform and feature matrix / audit (push) Has been cancelled
Release platform and feature matrix / matrix (false, linux-stable-minimal, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, macos-stable-portable, x86_64-apple-darwin, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, windows-stable-portable, x86_64-pc-windows-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-msrv-portable, x86_64-unknown-linux-gnu, 1.96.0) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-default, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-features, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-release-surface, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Dependency and supply-chain audit / audit (push) Has been cancelled
Native release artifact audit / audit (push) Has been cancelled
Imaging and meshing gate / native (push) Failing after 53s
JPEG 2000 feature / linux (push) Successful in 2m49s
Native Rust workspace compile / compile (push) Failing after 59s
Skia feature / linux (push) Has been cancelled
Complete first release candidate audit (#107)
2026-08-12 14:44:28 +00:00

82 lines
2.3 KiB
Rust

use std::time::Duration;
use libremetaverse_types::compat::{CancellationToken, Task};
use crate::Error;
pub struct Repeat;
impl Repeat {
pub async fn interval_with_time_span_action_cancellation_token_boolean(
poll_interval: Duration,
action: Box<dyn Fn() + Send + Sync>,
token: CancellationToken,
immediately: Option<bool>,
) -> Result<(), Error> {
if poll_interval.is_zero() {
return Err(Error::Argument);
}
if immediately.unwrap_or(false) {
action();
}
loop {
tokio::select! {
() = tokio::time::sleep(poll_interval) => action(),
() = token.cancelled() => return Ok(()),
}
}
}
pub async fn interval_with_time_span_func_cancellation_token_boolean(
poll_interval: Duration,
async_action: Box<dyn Fn() -> Task<()> + Send + Sync>,
token: CancellationToken,
immediately: Option<bool>,
) -> Result<(), Error> {
if poll_interval.is_zero() {
return Err(Error::Argument);
}
if immediately.unwrap_or(false) {
async_action().await?;
}
loop {
tokio::select! {
() = tokio::time::sleep(poll_interval) => async_action().await?,
() = token.cancelled() => return Ok(()),
}
}
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use libremetaverse_types::compat::CancellationTokenSource;
use super::*;
#[tokio::test]
async fn repeats_immediately_and_stops_on_cancellation() {
let source = CancellationTokenSource::new();
let token = source.token();
let count = Arc::new(AtomicUsize::new(0));
let action_count = Arc::clone(&count);
let cancel = source.clone();
Repeat::interval_with_time_span_action_cancellation_token_boolean(
Duration::from_millis(1),
Box::new(move || {
if action_count.fetch_add(1, Ordering::Relaxed) >= 2 {
cancel.cancel();
}
}),
token,
Some(true),
)
.await
.unwrap();
assert_eq!(count.load(Ordering::Relaxed), 3);
}
}