From 2a1919aba2c62dbeeffa7a859e429b20c3de4749 Mon Sep 17 00:00:00 2001 From: Christopher Acosta Date: Tue, 19 Mar 2024 22:27:59 +0100 Subject: [PATCH 1/5] Add Semaphore example for limiting the number of outgoing requests being sent in parallel. --- tokio/src/sync/semaphore.rs | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index d0ee12591ee..4ec28ab05cc 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -75,6 +75,49 @@ use std::sync::Arc; /// Ok(()) // Permit goes out of scope here, and is available again for acquisition /// } /// ``` +/// +/// ## Limit the number of outgoing requests being sent at the same time +/// In some scenarios, it might be required to limit the number of outgoing +/// requests being sent in parallel. This could be due to limits of a consumed +/// API or the network resources of the system the application is running on. +/// +/// This example uses an `Arc` with 10 permits. +/// Each task spawned is given a reference to the semaphore by cloning the `Arc`. +/// Before a task sends a request, it must acquire a permit from the semaphore by calling [`Semaphore::acquire`]. +/// This ensures that at most 10 requests are sent in parallel at any given time. +/// After a task has sent a request, it drops the permit to allow other tasks to send requests. +/// ``` +/// use std::sync::Arc; +/// use tokio::sync::Semaphore; +/// +/// #[tokio::main] +/// async fn main() { +/// // Define maximum number of parallel requests. +/// let semaphore = Arc::new(Semaphore::new(10)); +/// // Spawn many tasks that will send requests. +/// let mut jhs = Vec::new(); +/// for task_id in 0..100 { +/// let semaphore = semaphore.clone(); +/// let jh = tokio::spawn(async move { +/// // Acquire permit before sending request. +/// let _permit = semaphore.acquire().await.unwrap(); +/// // Send the request. +/// let response = send_request(task_id).await; +/// // Drop the permit after the request has been sent. +/// drop(_permit); +/// // Handle response. +/// // ... +/// }); +/// jhs.push(jh); +/// } +/// for jh in jhs { +/// jh.await.unwrap(); +/// } +/// } +/// # async fn send_request(task_id: usize) { +/// # // Send request. +/// # } +/// ``` /// /// ## Limit the number of incoming requests being handled at the same time /// From 56b0515cea1cdfddcd3ae1e4926d67696f4d4cff Mon Sep 17 00:00:00 2001 From: Christopher Acosta Date: Wed, 20 Mar 2024 22:00:46 +0100 Subject: [PATCH 2/5] Format example according to rustfmt --- tokio/src/sync/semaphore.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 4ec28ab05cc..41edfb74561 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -75,12 +75,10 @@ use std::sync::Arc; /// Ok(()) // Permit goes out of scope here, and is available again for acquisition /// } /// ``` -/// /// ## Limit the number of outgoing requests being sent at the same time /// In some scenarios, it might be required to limit the number of outgoing /// requests being sent in parallel. This could be due to limits of a consumed /// API or the network resources of the system the application is running on. -/// /// This example uses an `Arc` with 10 permits. /// Each task spawned is given a reference to the semaphore by cloning the `Arc`. /// Before a task sends a request, it must acquire a permit from the semaphore by calling [`Semaphore::acquire`]. @@ -89,7 +87,6 @@ use std::sync::Arc; /// ``` /// use std::sync::Arc; /// use tokio::sync::Semaphore; -/// /// #[tokio::main] /// async fn main() { /// // Define maximum number of parallel requests. From 6bfff59d37c5475ae8d2aa7ba158c36a68b16d75 Mon Sep 17 00:00:00 2001 From: Christopher Acosta Date: Thu, 21 Mar 2024 09:07:46 +0100 Subject: [PATCH 3/5] Add spacing back --- tokio/src/sync/semaphore.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 41edfb74561..584646caed4 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -75,18 +75,23 @@ use std::sync::Arc; /// Ok(()) // Permit goes out of scope here, and is available again for acquisition /// } /// ``` +/// /// ## Limit the number of outgoing requests being sent at the same time +/// /// In some scenarios, it might be required to limit the number of outgoing /// requests being sent in parallel. This could be due to limits of a consumed /// API or the network resources of the system the application is running on. +/// /// This example uses an `Arc` with 10 permits. /// Each task spawned is given a reference to the semaphore by cloning the `Arc`. /// Before a task sends a request, it must acquire a permit from the semaphore by calling [`Semaphore::acquire`]. /// This ensures that at most 10 requests are sent in parallel at any given time. /// After a task has sent a request, it drops the permit to allow other tasks to send requests. +/// /// ``` /// use std::sync::Arc; /// use tokio::sync::Semaphore; +/// /// #[tokio::main] /// async fn main() { /// // Define maximum number of parallel requests. From a110873857f2f019d99eb878780a8ba9c5e6c262 Mon Sep 17 00:00:00 2001 From: Christopher Acosta Date: Thu, 21 Mar 2024 22:42:38 +0100 Subject: [PATCH 4/5] Collect responses from tasks --- tokio/src/sync/semaphore.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 584646caed4..4c0befe3167 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -109,12 +109,19 @@ use std::sync::Arc; /// drop(_permit); /// // Handle response. /// // ... +/// +/// response /// }); /// jhs.push(jh); /// } +/// // Collect responses from tasks. +/// let mut responses = Vec::new(); /// for jh in jhs { -/// jh.await.unwrap(); +/// let response = jh.await.unwrap(); +/// responses.push(response); /// } +/// // Process responses. +/// // ... /// } /// # async fn send_request(task_id: usize) { /// # // Send request. From 2953f4eeb749a474c5531bf90de54f2e196cefcc Mon Sep 17 00:00:00 2001 From: Christopher Acosta Date: Thu, 21 Mar 2024 22:44:42 +0100 Subject: [PATCH 5/5] Format paragraph to 80-character lines --- tokio/src/sync/semaphore.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 4c0befe3167..a2b4074590b 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -82,11 +82,12 @@ use std::sync::Arc; /// requests being sent in parallel. This could be due to limits of a consumed /// API or the network resources of the system the application is running on. /// -/// This example uses an `Arc` with 10 permits. -/// Each task spawned is given a reference to the semaphore by cloning the `Arc`. -/// Before a task sends a request, it must acquire a permit from the semaphore by calling [`Semaphore::acquire`]. -/// This ensures that at most 10 requests are sent in parallel at any given time. -/// After a task has sent a request, it drops the permit to allow other tasks to send requests. +/// This example uses an `Arc` with 10 permits. Each task spawned is +/// given a reference to the semaphore by cloning the `Arc`. Before +/// a task sends a request, it must acquire a permit from the semaphore by +/// calling [`Semaphore::acquire`]. This ensures that at most 10 requests are +/// sent in parallel at any given time. After a task has sent a request, it +/// drops the permit to allow other tasks to send requests. /// /// ``` /// use std::sync::Arc;