Skip to content

Commit

Permalink
docs: add semaphore example
Browse files Browse the repository at this point in the history
Signed-off-by: Muhan Song <songmuhan@stu.pku.edu.cn>
  • Loading branch information
songmuhan committed Sep 29, 2023
1 parent 453c720 commit 4bcb5c4
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions tokio/src/sync/semaphore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,55 @@ use std::sync::Arc;
/// }
/// ```
///
/// ## Ensure Tests with Mutual Dependencies Run Sequentially
///
/// By default, Rust runs tests concurrently. However, in some scenarios, concurrent execution might lead to test interference.
/// For example, multiple tests might communicate with the same database, necessitating sequential execution to prevent data conflicts.
///
/// Consider the following scenario:
/// 1. `test_insert`: Inserts a key-value pair into the database, then retrieves the value using the same key to verify the insertion.
/// 2. `test_update`: After insertion, this test updates the key's value to a new one and verifies if the value has been accurately updated.
/// 3. `test_others`: This is a non-interfering test that can run concurrently with other tests.
///
/// For this example, it's essential that `test_insert` and `test_update` run sequentially, though their execution order is inconsequential.
/// Leveraging a semaphore with a single permit elegantly addresses this challenge.
///
/// ```
/// #[cfg(test)]
/// mod tests {
/// use tokio::sync::Semaphore;
/// // only one permit can be acquired
/// static PERMIT: Semaphore = Semaphore::const_new(1);
/// // initilization of database
/// static DB: database = database::setup();
/// #[tokio::test]
/// async fn test_insert() {
/// // acquire permit first
/// let permit = PERMIT.acquire().await.unwrap();
/// let (key, value) = ("name", 0);
/// DB.insert((key, value)).await;
/// assert_eq!(DB.get(key), value);
/// // undo the modification
/// DB.delete(key).await;
/// // permit dropped here
/// }
/// #[tokio::test]
/// async fn test_update() {
/// let permit = PERMIT.acquire().await.unwrap();
/// let (key, value) = ("name", 0);
/// DB.insert((key, value)).await;
/// let new_value = 1;
/// // update new value at the same key
/// DB.update((key, new_value)).await;
/// assert_eq!(DB.get(key).await, new_value);
/// DB.delete(key).await;
/// }
/// #[tokio::test]
/// async fn test_other() {
/// // this test can simualtenously run with test_insert and test_update.
/// }
/// }
/// ```
/// [`PollSemaphore`]: https://docs.rs/tokio-util/latest/tokio_util/sync/struct.PollSemaphore.html
/// [`Semaphore::acquire_owned`]: crate::sync::Semaphore::acquire_owned
#[derive(Debug)]
Expand Down

0 comments on commit 4bcb5c4

Please sign in to comment.