Skip to content

Commit

Permalink
sync: reorder Semaphore examples (#6031)
Browse files Browse the repository at this point in the history
  • Loading branch information
Darksonn committed Sep 23, 2023
1 parent f5b8cf9 commit b161633
Showing 1 changed file with 49 additions and 49 deletions.
98 changes: 49 additions & 49 deletions tokio/src/sync/semaphore.rs
Expand Up @@ -47,7 +47,7 @@ use std::sync::Arc;
/// }
/// ```
///
/// Limit the number of simultaneously opened files in your program.
/// ## Limit the number of simultaneously opened files in your program.
///
/// Most operating systems have limits on the number of open file
/// handles. Even in systems without explicit limits, resource constraints
Expand Down Expand Up @@ -76,7 +76,54 @@ use std::sync::Arc;
/// }
/// ```
///
/// Implement a simple token bucket for rate limiting
/// ## Limit the number of incoming requests being handled at the same time.
///
/// Similar to limiting the number of simultaneously opened files, network handles
/// are a limited resource. Allowing an unbounded amount of requests to be processed
/// could result in a denial-of-service, among many other issues.
///
/// This example uses an `Arc<Semaphore>` instead of a global variable.
/// To limit the number of requests that can be processed at the time,
/// we acquire a permit for each task before spawning it. Once acquired,
/// a new task is spawned; and once finished, the permit is dropped inside
/// of the task to allow others to spawn. Permits must be acquired via
/// [`Semaphore::acquire_owned`] to be movable across the task boundary.
/// (Since our semaphore is not a global variable — if it was, then `acquire` would be enough.)
///
/// ```no_run
/// use std::sync::Arc;
/// use tokio::sync::Semaphore;
/// use tokio::net::TcpListener;
///
/// #[tokio::main]
/// async fn main() -> std::io::Result<()> {
/// let semaphore = Arc::new(Semaphore::new(3));
/// let listener = TcpListener::bind("127.0.0.1:8080").await?;
///
/// loop {
/// // Acquire permit before accepting the next socket.
/// //
/// // We use `acquire_owned` so that we can move `permit` into
/// // other tasks.
/// let permit = semaphore.clone().acquire_owned().await.unwrap();
/// let (mut socket, _) = listener.accept().await?;
///
/// tokio::spawn(async move {
/// // Do work using the socket.
/// handle_connection(&mut socket).await;
/// // Drop socket while the permit is still live.
/// drop(socket);
/// // Drop the permit, so more tasks can be created.
/// drop(permit);
/// });
/// }
/// }
/// # async fn handle_connection(_socket: &mut tokio::net::TcpStream) {
/// # // Do work
/// # }
/// ```
///
/// ## Rate limiting using a token bucket
///
/// Many applications and systems have constraints on the rate at which certain
/// operations should occur. Exceeding this rate can result in suboptimal
Expand Down Expand Up @@ -159,53 +206,6 @@ use std::sync::Arc;
/// }
/// ```
///
/// Limit the number of incoming requests being handled at the same time.
///
/// Similar to limiting the number of simultaneously opened files, network handles
/// are a limited resource. Allowing an unbounded amount of requests to be processed
/// could result in a denial-of-service, among many other issues.
///
/// This example uses an `Arc<Semaphore>` instead of a global variable.
/// To limit the number of requests that can be processed at the time,
/// we acquire a permit for each task before spawning it. Once acquired,
/// a new task is spawned; and once finished, the permit is dropped inside
/// of the task to allow others to spawn. Permits must be acquired via
/// [`Semaphore::acquire_owned`] to be movable across the task boundary.
/// (Since our semaphore is not a global variable — if it was, then `acquire` would be enough.)
///
/// ```no_run
/// use std::sync::Arc;
/// use tokio::sync::Semaphore;
/// use tokio::net::TcpListener;
///
/// #[tokio::main]
/// async fn main() -> std::io::Result<()> {
/// let semaphore = Arc::new(Semaphore::new(3));
/// let listener = TcpListener::bind("127.0.0.1:8080").await?;
///
/// loop {
/// // Acquire permit before accepting the next socket.
/// //
/// // We use `acquire_owned` so that we can move `permit` into
/// // other tasks.
/// let permit = semaphore.clone().acquire_owned().await.unwrap();
/// let (mut socket, _) = listener.accept().await?;
///
/// tokio::spawn(async move {
/// // Do work using the socket.
/// handle_connection(&mut socket).await;
/// // Drop socket while the permit is still live.
/// drop(socket);
/// // Drop the permit, so more tasks can be created.
/// drop(permit);
/// });
/// }
/// }
/// # async fn handle_connection(_socket: &mut tokio::net::TcpStream) {
/// # // Do work
/// # }
/// ```
///
/// [`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 b161633

Please sign in to comment.