use dbuff::*;
use std::time::Duration;
#[derive(Debug, Clone, Default)]
struct AppData {
task_status: TaskStatus<String>,
}
#[derive(Debug, Clone, wherror::Error)]
#[error(debug)]
struct AppError;
struct SlowFetch(String);
#[async_trait::async_trait]
impl Command<()> for SlowFetch {
type Output = String;
type Error = AppError;
async fn execute(self, _: ()) -> Result<Self::Output, Self::Error> {
tokio::time::sleep(Duration::from_millis(500)).await;
Ok(self.0)
}
}
#[tokio::main]
async fn main() {
let rt = tokio::runtime::Handle::current();
let (domain, write_handle) =
SharedDomainData::with_coalesce(AppData::default(), Duration::from_micros(500));
tokio::spawn(write_handle.run());
println!("task_status: {:?}", domain.read().task_status);
println!("---");
let handle = domain
.bind((), rt.clone())
.exec(SlowFetch("hello from slow task".into()), |_, _: &String| {})
.tracked(|d: &mut AppData, status: TaskStatus<String>| d.task_status = status)
.go();
loop {
let state = domain.read();
match &state.task_status {
TaskStatus::Idle => {
println!("task_status: idle");
}
TaskStatus::Pending => {
println!("task_status: pending — aborting now");
handle.abort();
domain.modify(|d| d.task_status = TaskStatus::Aborted);
break;
}
TaskStatus::Resolved(v) => {
println!("task_status: resolved ({v:?}) — too fast, couldn't abort");
panic!("task resolved before we could abort");
}
TaskStatus::Error(e) => {
println!("task_status: error ({e})");
panic!("unexpected error");
}
TaskStatus::Aborted => {
println!("task_status: aborted (unexpectedly early)");
panic!("aborted before we triggered it");
}
}
tokio::time::sleep(Duration::from_millis(5)).await;
}
loop {
let state = domain.read();
match &state.task_status {
TaskStatus::Aborted => {
println!("task_status: aborted ✓");
break;
}
other => {
println!("task_status: {other:?} (waiting for abort)");
}
}
tokio::time::sleep(Duration::from_millis(5)).await;
}
tokio::time::sleep(Duration::from_millis(10)).await;
let state = domain.read();
println!("---");
println!("task_status = {:?}", state.task_status);
assert!(state.task_status.is_aborted());
}