Skip to content

Instantly share code, notes, and snippets.

@vinipsmaker
Last active April 29, 2016 05:31
Show Gist options
  • Save vinipsmaker/e3ead377702f0c66a8bec3102a9b5ee4 to your computer and use it in GitHub Desktop.
Save vinipsmaker/e3ead377702f0c66a8bec3102a9b5ee4 to your computer and use it in GitHub Desktop.

Comparison of coroutine libraries for Rust

NOTE: I didn't find any project with a good enough documentation. A "good enough" documentation would be more explicit about ownership of CPU share, controls and resources (e.g. how do multiple coroutines share the same thread? How do I migrate one coroutine to another thread?).

monkeys is a coroutine crate based on the async/await functions.

The async function spawns a coroutine and the await function awaits for a coroutine (or fiber if you prefer this vocabulary) to complete. This simple API is unsuited to expose higher-level building blocks as there is no way to query if a coroutine is ready. Without such a function, we can't efficiently implement a Vec<Future>::when_any-like algorithm, for instance.

monkeys currently doesn't expose an adapted network stack, even if the Rust language exposes an standardized API across all platforms.

simplesched looks a lot like monkeys except for the following items:

  • More meaningful names like spawn instead async and...
  • By the lack of online documentation, the fact that the build failed even when I fixed a few mistakes and no tags to know which commit was okay, I decided to not spend further time on this library.

The API is rather low level. It wasn't also clear how to integrate multiple coroutines into one event loop or network abstractions in this API.

So far this is the library where most effort was spent by the authors and the only one that fully integrates network and coroutines.

It tries to immitate threads API and hide the fact that coroutines are being used. To that end it differentiates itself from the other alternatives by hiding the executor object and making use of global functions that affect current coroutine like spawn, yield_now and sleep.

The yield_now model is very weak as it doesn't allow to retrieve a handle to resume such coroutine. The executor will run all remaining coroutines before going back to this one and all of them need to query if a previous operation was completed (readiness model) before passing the control back to the executor again or doing something useful with the result. This issue may not seem so problematic because the network stack is already integrated properly.

It's still complicated to efficiently integrate mioco with external event loops though because of the previously mentioned issue.

This library has several conceptual similarities with mioco and they won't be repeated here.

@zonyitoo
Copy link

zonyitoo commented Apr 29, 2016

I am the author of coroutine, simplesched and coio.

  1. simplesched was an experimental project before coio. I have already abandoned it because the main concept of it has already been merged into coio. So there is no need to spend time on it.
  2. coroutine is the earliest project that I created before simplesched and coio. I planned to let this project to be the backend support library for simplesched and coio, also for mioco, BUT in practice, raw level context switching APIs is much more suitable. So I created context-rs project, which contains the most low level context switching facilities. So ... I am still the maintainer of this project, but I haven't spent any time on this for a long time.
  3. coio and mioco were created nearly at the same time, but with different goal. Theoretically, the most obviously difference between them is: coio allows coroutines migrates between worker threads, and mioco is opposite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment