scheduler.rs 5.5 KB

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