#coroutine #async #stackful-coroutine #fiber #fibers

ruloom

A thin wrapper around 'corosensei' that provides support for stackful coroutines in Rust (like Loom in Java or goroutines in golang)

3 releases

new 0.1.2 Dec 16, 2024
0.1.1 Dec 16, 2024
0.1.0 Dec 16, 2024

#260 in Asynchronous

Download history 157/week @ 2024-12-11

157 downloads per month

MIT/Apache

26KB
561 lines

Rust-Loom (ruloom)

status

It is a Crate, which is intended to simplify asynchronous programming. You can write asynchronous code as if it were synchronous code. The name is a combination of "Rust" (ru) and "Loom" (see https://wiki.openjdk.org/display/loom/Main).

Documentation

https://docs.rs/ruloom/latest/ruloom/

Why

I love Rust, but am unhappy about how asynchronous programming is solved in Rust (currently). Although there have been big improvements recently (2024) (see https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html), the situation in Rust is still not satisfactory (my opinion).

  • Function coloring.
  • Dependence on a runtime (tokio, smol, ...).
  • Duplication of the standard library and other libraries: Example: Some libraries are sync, some async. RwLock, channels, file operations, network operations are available in 2 versions (sync and async).

In my opinion, Rust should have taken a different path:

  • Async/await (like today): In addition, the std-lib should have been prepared for this; at least the traits implemented by a runtime like Tokio or Smol should be available in the std-lib, so that libraries do not depend on a specific runtime.
  • In addition, Rust should support stackful coroutines (aka Fibers, similar to Go routines or Loom in Java). The std-lib should be prepared for this (can be switched on with a feature flag).

What does ruloom solve?

Ruloom is based on corosensei and allows asynchronous code to be written as if it were synchronous code.

// See, no 'async' keyword here.
// This is how you you write your application / library.
fn looks_like_a_sync_function_but_its_async() {
    // A future
    let future = smol::Timer::after(Duration::from_millis(10));
    // Await the future (suspends the current task)
    await_future(future); 
}

// You can the use smol or tokio to run your code / library / application.
fn run()  {
    smol::block_on(async {
        // convert back to a future.
        let future = to_future(||looks_like_a_sync_function_but_its_async());
        future.await;
    })
}

The two main functions of ruloom are:

  • await_future: Converts a future into a synchronous call. May only be used within to_future. Technical detail: If the future is pending, the current coroutine is suspended (stack switch).
  • to_future: Converts a synchronous function into a future. This future can then be executed by the selected runtime (Tokio, Smol, ...).

What problems does ruloom not solve?

It still does not offer a std-library, you still have a dependency on a certain runtime (like Tokio or Smol).

Furthermore, you have to be careful not to call any blocking functions.

Also, ruloom is (currently) an experiment; it is certainly not advisable to use this code in production.

Credits

  • 99.9% of the hard work is done by corosensei, ruloom is just a thin wrapper around this library.

License

Licensed under either of:

Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0) MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT) at your option.

Dependencies

~385KB