Skip to content

Commit baad270

Browse files
authored
sync: add Semaphore example for limiting the number of outgoing requests (#6419)
1 parent f9d78fb commit baad270

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

tokio/src/sync/semaphore.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,59 @@ use std::sync::Arc;
7676
/// }
7777
/// ```
7878
///
79+
/// ## Limit the number of outgoing requests being sent at the same time
80+
///
81+
/// In some scenarios, it might be required to limit the number of outgoing
82+
/// requests being sent in parallel. This could be due to limits of a consumed
83+
/// API or the network resources of the system the application is running on.
84+
///
85+
/// This example uses an `Arc<Semaphore>` with 10 permits. Each task spawned is
86+
/// given a reference to the semaphore by cloning the `Arc<Semaphore>`. Before
87+
/// a task sends a request, it must acquire a permit from the semaphore by
88+
/// calling [`Semaphore::acquire`]. This ensures that at most 10 requests are
89+
/// sent in parallel at any given time. After a task has sent a request, it
90+
/// drops the permit to allow other tasks to send requests.
91+
///
92+
/// ```
93+
/// use std::sync::Arc;
94+
/// use tokio::sync::Semaphore;
95+
///
96+
/// #[tokio::main]
97+
/// async fn main() {
98+
/// // Define maximum number of parallel requests.
99+
/// let semaphore = Arc::new(Semaphore::new(10));
100+
/// // Spawn many tasks that will send requests.
101+
/// let mut jhs = Vec::new();
102+
/// for task_id in 0..100 {
103+
/// let semaphore = semaphore.clone();
104+
/// let jh = tokio::spawn(async move {
105+
/// // Acquire permit before sending request.
106+
/// let _permit = semaphore.acquire().await.unwrap();
107+
/// // Send the request.
108+
/// let response = send_request(task_id).await;
109+
/// // Drop the permit after the request has been sent.
110+
/// drop(_permit);
111+
/// // Handle response.
112+
/// // ...
113+
///
114+
/// response
115+
/// });
116+
/// jhs.push(jh);
117+
/// }
118+
/// // Collect responses from tasks.
119+
/// let mut responses = Vec::new();
120+
/// for jh in jhs {
121+
/// let response = jh.await.unwrap();
122+
/// responses.push(response);
123+
/// }
124+
/// // Process responses.
125+
/// // ...
126+
/// }
127+
/// # async fn send_request(task_id: usize) {
128+
/// # // Send request.
129+
/// # }
130+
/// ```
131+
///
79132
/// ## Limit the number of incoming requests being handled at the same time
80133
///
81134
/// Similar to limiting the number of simultaneously opened files, network handles

0 commit comments

Comments
 (0)