util.rs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #![allow(clippy::type_complexity)]
  2. use crate::module::{CoreCloudService, WorkspaceUser};
  3. use lib_infra::retry::Action;
  4. use pin_project::pin_project;
  5. use std::{
  6. future::Future,
  7. marker::PhantomData,
  8. pin::Pin,
  9. sync::Arc,
  10. task::{Context, Poll},
  11. };
  12. pub(crate) type Builder<Fut> = Box<dyn Fn(String, Arc<dyn CoreCloudService>) -> Fut + Send + Sync>;
  13. #[allow(dead_code)]
  14. pub(crate) struct RetryAction<Fut, T, E> {
  15. token: String,
  16. cloud_service: Arc<dyn CoreCloudService>,
  17. user: Arc<dyn WorkspaceUser>,
  18. builder: Builder<Fut>,
  19. phantom: PhantomData<(T, E)>,
  20. }
  21. impl<Fut, T, E> RetryAction<Fut, T, E> {
  22. #[allow(dead_code)]
  23. pub(crate) fn new<F>(cloud_service: Arc<dyn CoreCloudService>, user: Arc<dyn WorkspaceUser>, builder: F) -> Self
  24. where
  25. Fut: Future<Output = Result<T, E>> + Send + Sync + 'static,
  26. F: Fn(String, Arc<dyn CoreCloudService>) -> Fut + Send + Sync + 'static,
  27. {
  28. let token = user.token().unwrap_or_else(|_| "".to_owned());
  29. Self {
  30. token,
  31. cloud_service,
  32. user,
  33. builder: Box::new(builder),
  34. phantom: PhantomData,
  35. }
  36. }
  37. }
  38. impl<Fut, T, E> Action for RetryAction<Fut, T, E>
  39. where
  40. Fut: Future<Output = Result<T, E>> + Send + Sync + 'static,
  41. T: Send + Sync + 'static,
  42. E: Send + Sync + 'static,
  43. {
  44. type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send + Sync>>;
  45. type Item = T;
  46. type Error = E;
  47. fn run(&mut self) -> Self::Future {
  48. let fut = (self.builder)(self.token.clone(), self.cloud_service.clone());
  49. Box::pin(RetryActionFut { fut: Box::pin(fut) })
  50. }
  51. }
  52. #[pin_project]
  53. struct RetryActionFut<T, E> {
  54. #[pin]
  55. fut: Pin<Box<dyn Future<Output = Result<T, E>> + Send + Sync>>,
  56. }
  57. impl<T, E> Future for RetryActionFut<T, E>
  58. where
  59. T: Send + Sync + 'static,
  60. E: Send + Sync + 'static,
  61. {
  62. type Output = Result<T, E>;
  63. fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  64. let mut this = self.project();
  65. this.fut.as_mut().poll(cx)
  66. }
  67. }