scheduler.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. use crate::queue::TaskQueue;
  2. use crate::store::TaskStore;
  3. use crate::{Task, TaskContent, TaskId, TaskState};
  4. use anyhow::Error;
  5. use lib_infra::future::BoxResultFuture;
  6. use std::collections::HashMap;
  7. use std::sync::Arc;
  8. use std::time::Duration;
  9. use tokio::sync::{watch, RwLock};
  10. use tokio::time::interval;
  11. pub struct TaskDispatcher {
  12. queue: TaskQueue,
  13. store: TaskStore,
  14. timeout: Duration,
  15. handlers: HashMap<String, Arc<dyn TaskHandler>>,
  16. notifier: watch::Sender<bool>,
  17. pub(crate) notifier_rx: Option<watch::Receiver<bool>>,
  18. }
  19. impl TaskDispatcher {
  20. pub fn new(timeout: Duration) -> Self {
  21. let (notifier, notifier_rx) = watch::channel(false);
  22. Self {
  23. queue: TaskQueue::new(),
  24. store: TaskStore::new(),
  25. timeout,
  26. handlers: HashMap::new(),
  27. notifier,
  28. notifier_rx: Some(notifier_rx),
  29. }
  30. }
  31. pub fn register_handler<T>(&mut self, handler: T)
  32. where
  33. T: TaskHandler,
  34. {
  35. let handler_id = handler.handler_id().to_owned();
  36. self.handlers.insert(handler_id, Arc::new(handler));
  37. }
  38. pub async fn unregister_handler<T: AsRef<str>>(&mut self, handler_id: T) {
  39. if let Some(handler) = self.handlers.remove(handler_id.as_ref()) {
  40. tracing::trace!(
  41. "{}:{} is unregistered",
  42. handler.handler_name(),
  43. handler.handler_id()
  44. );
  45. }
  46. }
  47. pub fn stop(&mut self) {
  48. let _ = self.notifier.send(true);
  49. self.queue.clear();
  50. self.store.clear();
  51. }
  52. pub(crate) async fn process_next_task(&mut self) -> Option<()> {
  53. let pending_task = self.queue.mut_head(|list| list.pop())?;
  54. let mut task = self.store.remove_task(&pending_task.id)?;
  55. let ret = task.ret.take()?;
  56. // Do not execute the task if the task was cancelled.
  57. if task.state().is_cancel() {
  58. let _ = ret.send(task.into());
  59. self.notify();
  60. return None;
  61. }
  62. let content = task.content.take()?;
  63. if let Some(handler) = self.handlers.get(&task.handler_id) {
  64. task.set_state(TaskState::Processing);
  65. tracing::trace!("{} task is running", handler.handler_name(),);
  66. match tokio::time::timeout(self.timeout, handler.run(content)).await {
  67. Ok(result) => match result {
  68. Ok(_) => {
  69. tracing::trace!("{} task is done", handler.handler_name(),);
  70. task.set_state(TaskState::Done)
  71. },
  72. Err(e) => {
  73. tracing::error!("{} task is failed: {:?}", handler.handler_name(), e);
  74. task.set_state(TaskState::Failure);
  75. },
  76. },
  77. Err(e) => {
  78. tracing::error!("{} task is timeout: {:?}", handler.handler_name(), e);
  79. task.set_state(TaskState::Timeout);
  80. },
  81. }
  82. } else {
  83. tracing::trace!("{} is cancel", task.handler_id);
  84. task.set_state(TaskState::Cancel);
  85. }
  86. let _ = ret.send(task.into());
  87. self.notify();
  88. None
  89. }
  90. pub fn add_task(&mut self, task: Task) {
  91. debug_assert!(!task.state().is_done());
  92. if task.state().is_done() {
  93. tracing::warn!("Should not add a task which state is done");
  94. return;
  95. }
  96. self.queue.push(&task);
  97. self.store.insert_task(task);
  98. self.notify();
  99. }
  100. pub fn read_task(&self, task_id: &TaskId) -> Option<&Task> {
  101. self.store.read_task(task_id)
  102. }
  103. pub fn cancel_task(&mut self, task_id: TaskId) {
  104. if let Some(task) = self.store.mut_task(&task_id) {
  105. task.set_state(TaskState::Cancel);
  106. }
  107. }
  108. pub fn next_task_id(&self) -> TaskId {
  109. self.store.next_task_id()
  110. }
  111. pub(crate) fn notify(&self) {
  112. let _ = self.notifier.send(false);
  113. }
  114. }
  115. pub struct TaskRunner();
  116. impl TaskRunner {
  117. pub async fn run(dispatcher: Arc<RwLock<TaskDispatcher>>) {
  118. dispatcher.read().await.notify();
  119. let debounce_duration = Duration::from_millis(300);
  120. let mut notifier = dispatcher
  121. .write()
  122. .await
  123. .notifier_rx
  124. .take()
  125. .expect("Only take once");
  126. loop {
  127. // stops the runner if the notifier was closed.
  128. if notifier.changed().await.is_err() {
  129. break;
  130. }
  131. // stops the runner if the value of notifier is `true`
  132. if *notifier.borrow() {
  133. break;
  134. }
  135. let mut interval = interval(debounce_duration);
  136. interval.tick().await;
  137. let _ = dispatcher.write().await.process_next_task().await;
  138. }
  139. }
  140. }
  141. pub trait TaskHandler: Send + Sync + 'static {
  142. fn handler_id(&self) -> &str;
  143. fn handler_name(&self) -> &str {
  144. ""
  145. }
  146. fn run(&self, content: TaskContent) -> BoxResultFuture<(), Error>;
  147. }
  148. impl<T> TaskHandler for Box<T>
  149. where
  150. T: TaskHandler,
  151. {
  152. fn handler_id(&self) -> &str {
  153. (**self).handler_id()
  154. }
  155. fn handler_name(&self) -> &str {
  156. (**self).handler_name()
  157. }
  158. fn run(&self, content: TaskContent) -> BoxResultFuture<(), Error> {
  159. (**self).run(content)
  160. }
  161. }
  162. impl<T> TaskHandler for Arc<T>
  163. where
  164. T: TaskHandler,
  165. {
  166. fn handler_id(&self) -> &str {
  167. (**self).handler_id()
  168. }
  169. fn handler_name(&self) -> &str {
  170. (**self).handler_name()
  171. }
  172. fn run(&self, content: TaskContent) -> BoxResultFuture<(), Error> {
  173. (**self).run(content)
  174. }
  175. }