MCPcopy Index your code
hub / github.com/conradludgate/futures-buffered

github.com/conradludgate/futures-buffered @v0.2.11

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.2.11 ↗ · + Follow
216 symbols 499 edges 19 files 61 documented · 28%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

futures-buffered

This project provides several future structures, all based around the FuturesUnorderedBounded primtive.

Much like futures::FuturesUnordered, this is a thread-safe, Pin friendly, lifetime friendly, concurrent processing stream.

This primtive is different to FuturesUnordered in that FuturesUnorderedBounded has a fixed capacity for processing count. This means it's less flexible, but produces better memory efficiency.

However, we also provide a FuturesUnordered which allocates larger FuturesUnorderedBounded automatically to mitigate these inflexibilities. This is based on a triangular-array concept to amortise the cost of allocating (much like with a Vec) without violating Pin constraints.

Benchmarks

Speed

Running 65536 100us timers with 256 concurrent jobs in a single threaded tokio runtime:

FuturesUnorderedBounded    [339.9 ms  364.7 ms  380.6 ms]
futures::FuturesUnordered  [377.4 ms  391.4 ms  406.3 ms]
                           [min         mean         max]

Memory usage

Running 512000 Ready<i32> futures with 256 concurrent jobs.

  • count: the number of times alloc/dealloc was called
  • alloc: the number of cumulative bytes allocated
  • dealloc: the number of cumulative bytes deallocated
futures::FuturesUnordered
    count:    1,024,004
    alloc:    40.96 MB
    dealloc:  40.96 MB

FuturesUnorderedBounded
    count:    4
    alloc:    8.28 KB
    dealloc:  8.28 KB

Conclusion

As you can see, FuturesUnorderedBounded massively reduces you memory overhead while providing a small performance gain. Perfect for if you want a fixed batch size

Examples

// create a tcp connection
let stream = TcpStream::connect("example.com:80").await?;

// perform the http handshakes
let (mut rs, conn) = conn::handshake(stream).await?;
runtime.spawn(conn);

/// make http request to example.com and read the response
fn make_req(rs: &mut SendRequest<Body>) -> ResponseFuture {
    let req = Request::builder()
        .header("Host", "example.com")
        .method("GET")
        .body(Body::from(""))
        .unwrap();
    rs.send_request(req)
}

// create a queue that can hold 128 concurrent requests
let mut queue = FuturesUnorderedBounded::new(128);

// start up 128 requests
for _ in 0..128 {
    queue.push(make_req(&mut rs));
}
// wait for a request to finish and start another to fill its place - up to 1024 total requests
for _ in 128..1024 {
    queue.next().await;
    queue.push(make_req(&mut rs));
}
// wait for the tail end to finish
for _ in 0..128 {
    queue.next().await;
}
use futures_buffered::join_all;

async fn foo(i: u32) -> u32 { i }

let futures = vec![foo(1), foo(2), foo(3)];

assert_eq!(join_all(futures).await, [1, 2, 3]);

Extension points exported contracts — how you extend this code

TryFuture (Interface)
A convenience for futures that return `Result` values that includes a variety of adapters tailored to such futures. Thi [1 …
src/lib.rs
BufferedStreamExt (Interface)
An extension trait for `Stream`s that provides a variety of convenient combinator functions. [1 implementers]
src/buffered.rs
BufferedTryStreamExt (Interface)
An extension trait for `Stream`s that provides a variety of convenient combinator functions. [1 implementers]
src/try_buffered.rs
TryStream (Interface)
A convenience for streams that return `Result` values that includes a variety of adapters tailored to such futures. Thi [1 …
src/lib.rs
Sealed (Interface)
(no doc) [2 implementers]
src/lib.rs

Core symbols most depended-on inside this repo

next
called by 27
src/slot_map.rs
push
called by 17
src/arc_slice.rs
sleep
called by 14
benches/batch.rs
push
called by 14
src/futures_unordered_bounded.rs
send
called by 14
src/merge_bounded.rs
push
called by 11
src/futures_unordered.rs
len
called by 11
src/slot_map.rs
capacity
called by 10
src/slot_map.rs

Shape

Method 117
Function 67
Class 25
Interface 5
Enum 2

Languages

Rust100%

Modules by API surface

src/arc_slice.rs31 symbols
src/futures_unordered_bounded.rs28 symbols
src/futures_unordered.rs24 symbols
src/futures_ordered_bounded.rs23 symbols
src/merge_unbounded.rs17 symbols
src/futures_ordered.rs17 symbols
src/slot_map.rs14 symbols
src/merge_bounded.rs13 symbols
tests/alloc.rs12 symbols
src/try_buffered.rs8 symbols
src/buffered/unordered.rs4 symbols
src/buffered.rs4 symbols

For agents

$ claude mcp add futures-buffered \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page