use std::{future::Future, task::Poll, time::Duration};
use tokio::{sync::mpsc, time::Instant};
trait MyTask {
fn run(&self) -> String;
}
#[derive(Clone)]
struct AutoTask {
name: String,
date: Instant,
cycle: Duration,
run: fn() -> String,
}
fn complex_fn() -> String {
"String_complex".into()
}
impl AutoTask {
fn next(&mut self) {
self.date += self.cycle;
}
}
impl Future for AutoTask {
type Output = AutoTask;
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
if Instant::now() >= self.date {
println!("start {}", self.name);
//Poll::Ready(self.name.clone())
let r = (self.run)();
println!("{r}");
Poll::Ready(self.clone())
} else {
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
#[tokio::main]
async fn main() {
let (tx, mut rx) = mpsc::channel(32);
let arc_task = AutoTask {
name: "task1".into(),
date: Instant::now() + Duration::from_secs(3),
cycle: Duration::from_secs(3),
run: complex_fn,
};
let t1 = tx.clone();
let _ = tokio::spawn(async move {
let future = arc_task.await;
let _ = t1.send(future).await;
});
//BUG: 反复clone,明显低效率方式*********************************
while let Some(mut message) = rx.recv().await {
let t2 = tx.clone();
let _ = tokio::spawn(async move {
message.next();
let future = message.await;
let _ = t2.send(future).await;
});
}
}