z4_types/
task.rs

1use std::sync::Arc;
2use tokio::{
3    sync::{mpsc::UnboundedSender, Mutex},
4    time::sleep,
5};
6
7use crate::{HandleResult, Handler, RoomId, Task, Tasks};
8
9/// Task message type
10pub enum TaskMessage<H: Handler> {
11    Result(RoomId, HandleResult<H::Param>),
12}
13
14/// Handle and listening tasks
15pub fn handle_tasks<H: Handler>(
16    room_id: RoomId,
17    tasks: Tasks<H>,
18    handler: Arc<Mutex<H>>,
19    sender: UnboundedSender<TaskMessage<H>>,
20) {
21    for task in tasks {
22        tokio::spawn(running(room_id, task, handler.clone(), sender.clone()));
23    }
24}
25
26/// Loop listening task
27async fn running<H: Handler>(
28    room_id: RoomId,
29    mut task: Box<dyn Task<H = H>>,
30    handler: Arc<Mutex<H>>,
31    sender: UnboundedSender<TaskMessage<H>>,
32) {
33    loop {
34        sleep(std::time::Duration::from_secs(task.timer())).await;
35
36        let mut handler_lock = handler.lock().await;
37        if let Ok(res) = task.run(&mut handler_lock).await {
38            let over = res.over;
39            let _ = sender.send(TaskMessage::Result(room_id, res));
40            if over {
41                drop(handler_lock);
42                break;
43            }
44        } else {
45            drop(handler_lock);
46            break;
47        }
48        drop(handler_lock);
49    }
50}