protocol_jobs_manager.rs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. use async_std::sync::Mutex;
  2. use futures::Future;
  3. use log::*;
  4. use smol::Task;
  5. use std::sync::Arc;
  6. use crate::net::error::NetResult;
  7. use crate::net::ChannelPtr;
  8. use crate::system::ExecutorPtr;
  9. pub type ProtocolJobsManagerPtr = Arc<ProtocolJobsManager>;
  10. pub struct ProtocolJobsManager {
  11. name: &'static str,
  12. channel: ChannelPtr,
  13. tasks: Mutex<Vec<Task<NetResult<()>>>>,
  14. }
  15. impl ProtocolJobsManager {
  16. pub fn new(name: &'static str, channel: ChannelPtr) -> Arc<Self> {
  17. Arc::new(Self {
  18. name,
  19. channel,
  20. tasks: Mutex::new(Vec::new()),
  21. })
  22. }
  23. pub fn start(self: Arc<Self>, executor: ExecutorPtr<'_>) {
  24. executor.spawn(self.handle_stop()).detach()
  25. }
  26. /// Spawns a new task adding it to the internal queue
  27. pub async fn spawn<'a, F>(&self, future: F, executor: ExecutorPtr<'a>)
  28. where
  29. F: Future<Output = NetResult<()>> + Send + 'a,
  30. {
  31. self.tasks.lock().await.push(executor.spawn(future))
  32. }
  33. /// This is run in start(). When the channel closes, we also stop all the tasks
  34. async fn handle_stop(self: Arc<Self>) {
  35. let stop_sub = self.channel.clone().subscribe_stop().await;
  36. // Wait for the stop signal
  37. // Not interested in the exact error
  38. let _ = stop_sub.receive().await;
  39. self.close_all_tasks().await
  40. }
  41. async fn close_all_tasks(self: Arc<Self>) {
  42. debug!(target: "net",
  43. "ProtocolJobsManager::close_all_tasks() [START, name={}, addr={}]",
  44. self.name,
  45. self.channel.address()
  46. );
  47. // Take all the tasks from our internal queue...
  48. let tasks = std::mem::take(&mut *self.tasks.lock().await);
  49. for task in tasks {
  50. // ... and cancel them
  51. let _ = task.cancel().await;
  52. }
  53. }
  54. }