Crate orb

Crate orb 

Source
Expand description

§Orb

Crates.io Documentation

Orb is an abstraction layer for writing runtime-agnostic async Rust code, allowing you to write code that works with different async runtimes, like tokio or smol.

We took the name Orb because it gets around :)

English | 中文

§Features

  • Runtime Agnostic: Write code that works with multiple async runtimes
  • Trait-Based: Clean, well-defined interfaces for async operations
  • Extensible: Easy to implement support for new runtimes
  • Lightweight: No overhead abstraction layer

§The goal

The main goal is to decouple your application logic from specific async runtime implementations, allowing you to:

  • Write portable async code that works at the same time in combination of multiple runtimes
  • Switch to new runtimes without changing your core logic
  • Test your code with different runtime characteristics

This is a side project during the development of razor-rpc. Because:

  • There is no established standard for designing different runtimes, when developing shared libraries, developers often only target specific runtimes.
  • Using too many #[cfg(feature=xxx)] in code makes it hard to read.
  • Runtimes like smol ecology enable you to customize executors, but there’s high learning cost, and lack utility functions (for example, there’s no timeout function in async-io or smol).
  • Passing features through sub-projects through multiple layers of cargo dependencies is even more difficult. (that’s why we don’t use feature in this crate)
  • If users want to customize a runtime for their own needs, they face the dilemma of incomplete ecosystem support.
  • Some projects like Hyper define abstraction layers, having each project do this individually is a huge maintenance cost.

This is why this crate was written.

§Usage

To use Orb, you need to depend on both the core orb crate and a runtime adapter crate like orb-tokio or orb-smol.

In your Cargo.toml:

[dependencies]
# when you write runtime agnostic codes
orb = "0"
# when you setup as end-user
orb-tokio = "0"
# or
orb-smol = "0"

There’s a global trait AsyncRuntime that combines all features at the crate level, and adding use orb::prelude::* will import all the traits you need.

There are some variants of the new() function, also refer to the documentation in the sub-crates:

§License

This project is licensed under the MIT License - see the LICENSE file for details.

§Modules

  • runtime - Traits for task spawn, join and block_on.
  • io - Traits for asynchronous I/O operations, and buffered I/O wrapper.
  • net - Wrapper types for networking, and a “unify” type for tcp + unix stream.
  • time - Traits for time-related operations like sleeping and intervals
  • utils - Utility types and functions

At top level AsyncRuntime trait will combine all the capabilities, including AsyncExec, AsyncIO, and AsyncTime.

You can write your own trait by inheriting AsyncRuntime or any other trait, to provide extra functions along with the runtime object. There’s an blanket trait to auto impl AsyncRuntime on anything that is Deref<Target> to an AsyncRuntime.

pub trait AsyncRuntime: AsyncExec + AsyncIO + AsyncTime {}

impl<F: std::ops::Deref<Target = T> + Send + Sync + 'static, T: AsyncRuntime> AsyncRuntime for F {}

Simimlar blanket trait can be found on other sub traits.

§Important Notes

When working with spawned tasks, be aware that some runtimes (like smol) will cancel the future if you drop the task handle without explicitly detaching it. If you want a task to continue running in the background, you must call AsyncJoinHandle::detach rather than just dropping the handle.

Modules§

io
Asynchronous I/O traits and utilities.
net
TCP and Unix domain socket listener implementations.
prelude
Re-export all the traits you need
runtime
Runtime execution traits for async task management.
time
Time-related traits and utilities for async operations.
utils
Utility types and functions for async operations.

Traits§

AsyncRuntime
A marker trait that combines all the core async runtime capabilities, including AsyncExec, AsyncIO, and AsyncTime. It serves as a convenient way to specify that a type provides all the core async runtime functionality.