shared.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. use std::sync::Arc;
  2. use tokio::sync::{Mutex, MutexGuard};
  3. use tokio::time::{timeout, Duration};
  4. // #[derive(Clone)] See issue #2
  5. pub struct Shared<T> {
  6. pub data: Arc<Mutex<T>>,
  7. /// Number of seconds to consider a dead lock
  8. pub lock_timeout: u64,
  9. }
  10. impl<T> Clone for Shared<T> {
  11. fn clone(&self) -> Self {
  12. Self {
  13. data: self.data.clone(),
  14. lock_timeout: self.lock_timeout,
  15. }
  16. }
  17. }
  18. impl<T> Shared<T> {
  19. /// Creates a new Shared of data T
  20. ///
  21. /// A lock timeout of 30 seconds is assigned by default (Use Shared::with_timeout to set the timeout yourself, or just edit the field as it is public)
  22. ///
  23. /// > Want to see a complete example, look at doc_example in the examples directory
  24. ///
  25. /// Example:
  26. /// ```
  27. /// use shared::Shared;
  28. ///
  29. /// // #[derive(Clone)]
  30. /// // Clone is no longer needed as of v0.2.0
  31. /// struct Person {
  32. /// pub name: String,
  33. /// pub age: u16
  34. /// }
  35. ///
  36. /// #[tokio::main]
  37. /// async fn main() {
  38. /// let shared_data = Shared::new(Person{
  39. /// name: "Test Dummy".to_string(),
  40. /// age: 30
  41. /// });
  42. ///
  43. /// // See Shared::lock for using it
  44. /// }
  45. /// ```
  46. pub fn new(data: T) -> Self {
  47. Shared {
  48. data: Arc::new(Mutex::new(data)),
  49. lock_timeout: 30_u64,
  50. }
  51. }
  52. /// Creates a new Shared of data T with a given timeout in seconds
  53. pub fn with_timeout(data: T, timeout: u64) -> Self {
  54. Shared { data: Arc::new(Mutex::new(data)), lock_timeout: timeout }
  55. }
  56. /// Acquire lock
  57. ///
  58. /// Will wait so many seconds as defined by lock_timeout (This will panic once the timeout is reached)
  59. ///
  60. /// > Want to see a complete example, look at doc_example in the examples directory
  61. ///
  62. /// Using:
  63. /// ```
  64. /// // See Shared::new for creating a Shared<Person>
  65. ///
  66. /// { // Direct access
  67. /// let person = shared_data.lock().await;
  68. /// println!("Person{{name: {}, age: {}}}", person.name, person.age);
  69. /// }
  70. ///
  71. /// // Using it as a parameter
  72. /// async fn get_older(shared: Shared<Person>) {
  73. /// let mut person = shared.lock().await;
  74. /// person.age += 1;
  75. /// }
  76. ///
  77. /// // Calling
  78. /// get_older(shared_data.clone()).await;
  79. /// ```
  80. pub async fn lock(&self) -> MutexGuard<'_, T> {
  81. let result = timeout(Duration::from_secs(self.lock_timeout), self.data.lock()).await;
  82. if let Ok(guard) = result {
  83. return guard;
  84. }
  85. panic!(
  86. "Failed to acquire lock in {} seconds. Deadlock?",
  87. self.lock_timeout
  88. );
  89. // self.data.lock().await
  90. }
  91. }