task.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. use crate::TaskHandlerId;
  2. use std::cmp::Ordering;
  3. use tokio::sync::oneshot::{Receiver, Sender};
  4. #[derive(Eq, Debug, Clone, Copy)]
  5. pub enum QualityOfService {
  6. Background,
  7. UserInteractive,
  8. }
  9. impl PartialEq for QualityOfService {
  10. fn eq(&self, other: &Self) -> bool {
  11. matches!(
  12. (self, other),
  13. (Self::Background, Self::Background) | (Self::UserInteractive, Self::UserInteractive)
  14. )
  15. }
  16. }
  17. pub type TaskId = u32;
  18. #[derive(Eq, Debug, Clone, Copy)]
  19. pub struct PendingTask {
  20. pub qos: QualityOfService,
  21. pub id: TaskId,
  22. }
  23. impl PartialEq for PendingTask {
  24. fn eq(&self, other: &Self) -> bool {
  25. self.id.eq(&other.id)
  26. }
  27. }
  28. impl PartialOrd for PendingTask {
  29. fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  30. Some(self.cmp(other))
  31. }
  32. }
  33. impl Ord for PendingTask {
  34. fn cmp(&self, other: &Self) -> Ordering {
  35. match (self.qos, other.qos) {
  36. // User interactive
  37. (QualityOfService::UserInteractive, QualityOfService::UserInteractive) => self.id.cmp(&other.id),
  38. (QualityOfService::UserInteractive, _) => Ordering::Greater,
  39. (_, QualityOfService::UserInteractive) => Ordering::Less,
  40. // background
  41. (QualityOfService::Background, QualityOfService::Background) => self.id.cmp(&other.id),
  42. }
  43. }
  44. }
  45. pub enum TaskContent {
  46. Text(String),
  47. Blob(Vec<u8>),
  48. }
  49. #[derive(Debug, Eq, PartialEq, Clone)]
  50. pub enum TaskState {
  51. Pending,
  52. Processing,
  53. Done,
  54. Failure,
  55. Cancel,
  56. Timeout,
  57. }
  58. impl TaskState {
  59. pub fn is_pending(&self) -> bool {
  60. matches!(self, TaskState::Pending)
  61. }
  62. pub fn is_done(&self) -> bool {
  63. matches!(self, TaskState::Done)
  64. }
  65. pub fn is_cancel(&self) -> bool {
  66. matches!(self, TaskState::Cancel)
  67. }
  68. pub fn is_processing(&self) -> bool {
  69. matches!(self, TaskState::Processing)
  70. }
  71. pub fn is_failed(&self) -> bool {
  72. matches!(self, TaskState::Failure)
  73. }
  74. }
  75. pub struct Task {
  76. pub id: TaskId,
  77. pub handler_id: TaskHandlerId,
  78. pub content: Option<TaskContent>,
  79. pub qos: QualityOfService,
  80. state: TaskState,
  81. pub ret: Option<Sender<TaskResult>>,
  82. pub recv: Option<Receiver<TaskResult>>,
  83. }
  84. impl Task {
  85. pub fn background(handler_id: &str, id: TaskId, content: TaskContent) -> Self {
  86. Self::new(handler_id, id, content, QualityOfService::Background)
  87. }
  88. pub fn user_interactive(handler_id: &str, id: TaskId, content: TaskContent) -> Self {
  89. Self::new(handler_id, id, content, QualityOfService::UserInteractive)
  90. }
  91. pub fn new(handler_id: &str, id: TaskId, content: TaskContent, qos: QualityOfService) -> Self {
  92. let handler_id = handler_id.to_owned();
  93. let (ret, recv) = tokio::sync::oneshot::channel();
  94. Self {
  95. handler_id,
  96. id,
  97. content: Some(content),
  98. qos,
  99. ret: Some(ret),
  100. recv: Some(recv),
  101. state: TaskState::Pending,
  102. }
  103. }
  104. pub fn state(&self) -> &TaskState {
  105. &self.state
  106. }
  107. pub(crate) fn set_state(&mut self, status: TaskState) {
  108. self.state = status;
  109. }
  110. }
  111. pub struct TaskResult {
  112. pub id: TaskId,
  113. pub state: TaskState,
  114. }
  115. impl std::convert::From<Task> for TaskResult {
  116. fn from(task: Task) -> Self {
  117. TaskResult {
  118. id: task.id,
  119. state: task.state().clone(),
  120. }
  121. }
  122. }