7 releases

Uses new Rust 2024

new 0.1.0-rc.7 Apr 12, 2025
0.1.0-rc.6 Apr 6, 2025
0.1.0-rc.2 Mar 13, 2025

#301 in Concurrency

Download history 102/week @ 2025-03-05 144/week @ 2025-03-12 1/week @ 2025-03-19 57/week @ 2025-03-26 450/week @ 2025-04-02

660 downloads per month

Apache-2.0 OR MIT

60KB
898 lines

flag-bearer: a generic async semaphore

Semaphores are very useful primitives, but the default tokio Semaphore is limited in it's functionality.

This crate aims to fill a gap left by tokio, to have extra functionality to track to permits available.

Example usecase

You want to limit number of active HTTP requests, as well as total buffer allocations for the body.

You could define the semaphore state like so.

use flag_bearer::{Semaphore, SemaphoreState};

#[derive(Debug)]
pub struct SemaphoreCounter {
    bytes: u64,
    requests: usize,
};

pub struct Request {
    bytes: u64,
}

impl SemaphoreState for SemaphoreCounter {
    type Params = Request;
    type Permit = Request;

    fn acquire(&mut self, params: Self::Params) -> Result<Self::Permit, Self::Params> {
        if self.bytes >= params.bytes && self.requests > 0 {
            self.bytes -= params.bytes;
            self.requests -= 1;

            Ok(params)
        } else {
            Err(params)
        }
    }

    fn release(&mut self, permit: Self::Permit) {
        self.bytes += permit.bytes;
        self.requests += 1;
    }
}

let semaphore = Semaphore::new_fifo(SemaphoreCounter {
    bytes: 10 * 1024 * 1024, // 10 MiB.
    requests: 10, // 10 requests.
})

Dependencies

~0.3–5MB