scheduler.rs 5.1 KB

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