The feature-rich, portable async channel library

Overview

The feature-rich, portable async channel library > crates.io > docs.rs

Why use Postage?

  • Includes a rich set of channels. | barrier | broadcast | dispatch | mpsc | oneshot | watch
  • Works with any executor.
    • Currently regressions are written for tokio and async-std.
    • With the futures-traits feature, channels implement the futures Sink/Stream traits.
  • Thoroughly tested.
    • Channels have full unit test coverage, and integration test coverage with multiple async executors.
  • Includes built-in Sink and Stream combinators.
    • Sinks can be chained and filtered.
    • Streams can be chained, filtered, mapped, and merged.
    • Sinks and streams can log their values, for easy app debugging.

Channels

postage::barrier

Barrier channels can be used to synchronize events, but do not transmit any data. When the sender is dropped (or tx.send(()) is called), the receiver is awoken. This can be used to asynchronously coordinate actions between tasks.

postage::broadcast

The broadcast channel provides reliable broadcast delivery between multiple senders and multiple receivers. The channel has a fixed capacity, and senders are suspended if the buffer is filled.

When a receiver is cloned, both receivers will be sent the same series of messages.

Senders also provide a subscribe() method which creates a receiver that will observe all messages sent after the call to subscribe.

postage::dispatch

The dispatch channel provides multi-sender, multi-receiver message dispatch. A message will be observed by at most one reciever. The channel has a fixed capacity, and senders are suspended if the buffer is filled.

Receivers can be created with rx.clone(), or tx.subscribe().

postage::mpsc

Postage includes a fixed-capacity multi-producer, single-consumer channel. The producer can be cloned, and the sender task is suspended if the channel becomes full.

postage::oneshot

Oneshot channels transmit a single value between a sender and a reciever. Neither can be cloned. If the sender drops, the receiver recieves a None value.

postage::watch

Watch channels can be used to asynchronously transmit state. When receivers are created, they immediately recieve an initial value. They will also recieve new values, but are not guaranteed to recieve every value.

Values transmitted over watch channels must implement Default. A simple way to achieve this is to transmit Option.

Benchmarks

Benchmarks of postage channels, and comparable async-std/tokio channels.

  • send/recv measures the total time to send and receive an item.
  • send full measures the time to send an item and get a Poll::Pending value on a full channel.
  • recv empty measures the time to get a Poll::Pending value on an empty channel.

All benchmarks were taken with criterion and are in the benches directory.

Package Channel send/recv send full recv empty
broadcast postage 144ns 6ns 7ns
broadcast tokio 88ns (-38%) 49ns 39ns
-
dispatch postage 87ns 26ns 26ns
dispatch async_std 41ns (-52%) 10ns 10ns
-
mpsc postage 79ns 25ns 27ns
mpsc tokio 132ns (+67%) 1ns 31ns
-
watch postage 96ns - 7ns
watch tokio 74ns (-22%) - 75ns
You might also like...
Golang like WaitGroup implementation for sync/async Rust.

wg Golang like WaitGroup implementation for sync/async Rust.

single file, std only, async Rust executor

whorl - A single file, std only, async Rust executor whorl was created to teach you how async executors work in Rust. It is not the fastest executor n

Async `TryFrom/TryInto` traits

async-convert Async TryFrom/TryInto traits API Docs | Releases | Contributing Installation $ cargo add async-convert Safety This crate uses #![deny(un

Simple async codec for rkyv. Reuses streaming buffer for maximum speed

rkyv_codec Simple async codec for rkyv. Reuses streaming buffer for maximum speed! This crate provides a makeshift adaptor for streaming &ArchivedObj

You can name anonymous Future from async fn without dyn or Box!

rename-future You can name anonymous Future from async fn without dyn or Box! PLEASE READ THIS THIS PROJECT NOT YET WELL TESTED! DON'T USE THIS IN PRO

The most fundamental type for async synchronization: an intrusive linked list of futures

wait-list This crate provides WaitList, the most fundamental type for async synchronization. WaitList is implemented as an intrusive linked list of fu

Ector is an open source async, no-alloc actor framework for embedded devices

Ector is an open source async, no-alloc actor framework for embedded devices. Ector is an open source async, no-alloc actor framework for embedded dev

Async variant of Tonic's `interceptor` function

Tonic Async Interceptor This crate contains AsyncInterceptor, an async variant of Tonic's Interceptor. Other than accepting an async interceptor funct

Use winit like the async runtime you've always wanted

async-winit Use winit like the async runtime you've always wanted. winit is actually asynchronous, contrary to popular belief; it's just not async. It

Releases(v0.5.0)
  • v0.5.0(Apr 14, 2022)

    Changes

    • Modified futures::sink::Sink implementations to return the item on error (SendError<T>) #45
    • Added watch::Sender::subscribe which returns a Receiver #46

    Documentation

    • Add examples covering all channels, and use in async_std/futures/tokio. #48
    • Update benchmarks, add some rustdoc. #53

    Fixes

    • A waiting oneshot receiver was not notified when the sender was dropped #44
    • Use parking_lot for internal synchronization. #47
    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Feb 8, 2021)

    • If the futures-traits feature is enabled, implementfutures::Sink and futures::Stream for senders and receivers #39
    • Add cargo feature documentation to docs.rs #5
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jan 31, 2021)

    Enhancements

    • Add a dispatch channel. A multi-producer, multi-consumer queue #33
    • Add .borrow() and .borrow_mut() to the watch sender #32
    • Add .blocking_send() and .blocking_recv() to the Sink/Stream traits #31
    • Remove the beta tag, as cross-platform tests have been implemented #29

    Misc

    • Refactor logic when channel internals return Pending, improving performance in this case #34
    Source code(tar.gz)
    Source code(zip)
  • v0.3.3(Jan 24, 2021)

  • v0.3.2(Jan 20, 2021)

    Fixes

    • Fix a concurrency bug in the barrier and mpsc channels that could occur if a channel is closed while another thread is going to return PollRecv::Pending. #18
    • Significantly improve the performance of the broadcast channel by removing/minimizing locks. #18
    • Strengthen static assertions on Send and Sync bounds for channel endpoints.

    Tests

    • Add benchmarks covering all channels #17
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Jan 18, 2021)

  • v0.3.0(Jan 18, 2021)

    Breaking Changes

    • Create a Context type (similar to std::task::Context) that contains an Option<&'a Waker>. This allows Sink::try_send and Stream::try_recv to be zero cost if the try returns pending. #9
    • Move postage::Stream to postage::stream::Stream. #11
    • Move postage::Sink to postage::Sink::Sink. #11

    Changes

    • Add the postage::prelude module with the Sink and Stream traits.
    • Significantly improve documentation coverage and add several doctests. #12
    • Log type names in the Stream/Sink logging combinators. The format is now: [postage::stream::stream_log] <my::Message> Message(1) #13
    • Use a lock-free notifier queue. #6

    Bugfixes/Tests

    • Fix a bug that caused very rare 'clone monster' broadcast test failures.
    • Add test coverage of the combinator APIs. #11
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Jan 18, 2021)

    • Completely rewrite the broadcast channel, and significantly improve test coverage.
    • Test broadcast and mpsc channels at multiple channel sizes, ranging from 2 to 64.
    • Add 'clone monster' tests that repeatedly clone senders and receivers, attempting to interfere with the flow of messages between an established pair.
    • Fix 'blocking bugs' in the mpsc and watch channels, where occasionally both ends would return Pending and never resolve.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Jan 16, 2021)

    • Fix a torrent of bugs in the broadcast channel
    • Dramatically improve unit test and integration test coverage
    • Add rustdocs, and more readme content.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jan 16, 2021)

    General

    • Improve the SendFuture / RecvFuture design. Require Unpin, and use PhantomPin.
    • Remove the Sized bound for Sink and Stream.
    • Add a barrier channel, which transmits a value when the sender is dropped.
    • Add tokio and async-std tests covering each channel impl
    • Implement std::error::Error for all error types

    Combinators

    • Add logging combinators
    • Fix a merge stream bug, where the receiver would block (even though the second stream had an available item).

    Broadcast

    • Extract a multi-producer, multi-consumer circular buffer utility, and fix many bugs with the broadcast channel
    • Require Send, and add unsafe Sync impls for a few types (that are safe due to atomics + unsafecell)

    Watch

    • Add watch::Receiver::borrow
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Jan 16, 2021)

Owner
Austin Jones
Backend Engineer & Generative Artist. Extensive experience in Rust and Java. Author and maintainer of tab-rs, a terminal multiplexer.
Austin Jones
hy-rs, pronounced high rise, provides a unified and portable to the hypervisor APIs provided by various platforms.

Introduction The hy-rs crate, pronounced as high rise, provides a unified and portable interface to the hypervisor APIs provided by various platforms.

S.J.R. van Schaik 12 Nov 1, 2022
Mount portable directory as consistent user directory.

PortableDesktop Mount portable directory as consistent user directory. PortableDesktopCli help PortableDesktopCli [options] <Target Path> <Link Path>

Kerwin Bryant 3 May 8, 2023
A naive buffered/sync channel implementation in Rust, using the queue data structure

buffered-queue-rs Introduction This is my attempt at a simple and very naive buffered/synced queue implementation in Rust. The base thread-safe queue

Dhruv 4 Jul 22, 2023
This contract is to provide vesting account feature for the both cw20 and native tokens, which is controlled by a master address

Token Vesting This contract is to provide vesting account feature for the both cw20 and native tokens, which is controlled by a master address. Instan

yys 7 Oct 7, 2022
BPF library for Async Rust, complementary for libbpf-rs.

libbpf-async A library for writing BPF programs in Async Rust, complementary for libbpf-rs, Rust wrapper for libbpf. Currently, this provides Async-fr

FUJITA Tomonori 13 Nov 9, 2022
Rust library for one-time async initialization

async-lazy An async version of once_cell::sync::Lazy, std::sync::OnceLock or lazy_static. Uses tokio's sychronization primitives. This crate offers an

Jules Bertholet 5 Jun 9, 2023
Async executor for WebAssembly

There are a number of async task executors available in Rust's ecosystem. However, most (if not all?) of them rely on primitives that might not be available or optimal for WebAssembly deployment at the time.

wasm.rs 65 Dec 31, 2022
Mix async code with CPU-heavy thread pools using Tokio + Rayon

tokio-rayon Mix async code with CPU-heavy thread pools using Tokio + Rayon Resources Documentation crates.io TL;DR Sometimes, you're doing async stuff

Andy Barron 74 Jan 2, 2023
Another Async IO Framework based on io_uring

kbio, the Async IO Framework based on io_uring, is used in KuiBaDB to implement async io. Features Support multi-threading concurrent task submission.

KuiBaDB 59 Oct 31, 2022
async-alloc-counter measures max allocations in a future invocation

async-alloc-counter measures max allocations in a future invocation see examples/ for usage This allocator can be used as follows: use async_alloc_cou

Geoffroy Couprie 2 Dec 3, 2021