Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ibraheemdev/firefly
High performance concurrent channels.
https://github.com/ibraheemdev/firefly
Last synced: 28 days ago
JSON representation
High performance concurrent channels.
- Host: GitHub
- URL: https://github.com/ibraheemdev/firefly
- Owner: ibraheemdev
- License: mit
- Created: 2022-06-07T20:29:49.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2022-10-23T22:44:26.000Z (about 2 years ago)
- Last Synced: 2023-04-10T02:58:13.279Z (over 1 year ago)
- Language: Rust
- Homepage:
- Size: 212 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `firefly`
A collection of high performance concurrent channels.
```rust
// create a SPSC channel with a capacity of 2
let (mut tx, mut rx) = firefly::spsc::bounded(2);task::spawn(async move {
// send a message across asynchronously
tx.send(42).await.unwrap();
});// receive the message synchronously
assert_eq!(rx.recv_blocking().unwrap(), 42);
```## Channel Flavors
Firefly provides a variety of channel flavors, optimized for specific use cases:
- [`spsc::bounded`](https://docs.rs/firefly/latest/firefly/spsc/fn.bounded.html)
- [`spsc::unbounded`](https://docs.rs/firefly/latest/firefly/spsc/fn.unbounded.html)
- [`mpsc::bounded`](https://docs.rs/firefly/latest/firefly/mpsc/fn.bounded.html)
- [`mpsc::unbounded`](https://docs.rs/firefly/latest/firefly/mpsc/fn.unbounded.html)
- [`mpmc::bounded`](https://docs.rs/firefly/latest/firefly/mpmc/fn.bounded.html)
- [`mpmc::unbounded`](https://docs.rs/firefly/latest/firefly/mpmc/fn.unbounded.html)In general, a channel flavor higher up on the list is likely to be more performant
than a more generic one lower down.---
Bounded channels are created with a bounded capacity; the maximum number of messages
that can be held at a given time:```rust
// create a channel that can hold at most 8 messages at a time
let (mut tx, mut rx) = firefly::spsc::bounded(8);task::spawn(async move {
for i in 0..100 {
// send a message, potentially waiting until capacity frees up
tx.send(i).await.unwrap();
}
});// block until messages are sent
while let Ok(i) = rx.recv_blocking() {
println!("{i}");
}
```Unbounded channels on the other hand are unlimited in their capacity, meaning that
sending never blocks:```rust
// create an unbounded channel
let (mut tx, mut rx) = firefly::spsc::unbounded();task::spawn(async move {
// send an arbitrary amount of messages
for i in 0..10_000 {
tx.send(i).unwrap();
}
});// block until all messages are sent
while let Ok(i) = rx.recv_blocking() {
println!("{i}");
}
```## Blocking
Send and receive operations can be performed four different ways:
- Non-blocking (returns immediately with success or failure).
- Asynchronously (blocks the async task).
- Blocking (blocks the thread until the operation succeeds or the channel disconnects).
- Blocking with a timeout (blocks upto a maximum duration of time).```rust
let (mut tx, mut rx) = firefly::spsc::bounded(4);thread::spawn(move || {
for _ in 0..3 {
// this can never fail because we never exceed the capacity
tx.try_send(42).unwrap();
}
});// attempt to receive the message without blocking
match rx.try_recv() {
Ok(x) => assert_eq!(x, 42),
Err(_) => println!("message has not been sent yet")
}// block until the message is sent
assert_eq!(rx.recv_blocking(), Ok(42));// block for at most 1 second
match rx.recv_blocking_timeout(Duration::from_secs(1)) {
Ok(x) => assert_eq!(x, 42),
Err(_) => println!("message took too long to send")
}// spawn a task that receives the message asynchronously
task::spawn(async move {
assert_eq!(rx.recv().await, Ok(42));
});
```All channels can be used to "bridge" between async and sync code:
```rust
let (mut tx, mut rx) = firefly::spsc::bounded(8);// send messages synchronously
thread::spawn(move || {
for i in 0..16 {
tx.send_blocking(i).unwrap()
}
});// receive asynchronously
task::spawn(async move {
while let Ok(i) = rx.recv().await {
println!("{i}");
}
});
```## Disconnection
When all senders or receivers of a given channel are dropped, the channel is
disconnected. Any attempts to send a message will fail. Any remaining messages
in the channel can be received, but subsequent attempts to receive will also
fail:```rust
let (mut tx, mut rx) = firefly::spsc::unbounded();tx.send(1).unwrap();
tx.send(2).unwrap();// disconnect the sender
drop(tx);// any remaining messages can be received
assert_eq!(rx.recv().await, Ok(1));
assert_eq!(rx.recv().await, Ok(2));// subsequent attempts will error
assert_eq!(rx.recv().await, Err(firefly::RecvError));
```