A small and fast async runtime

This crate simply re-exports other smaller async crates (see the source)

smol

A small and fast async runtime.

This crate simply re-exports other smaller async crates (see the source).

To use tokio-based libraries with smol, apply the async-compat adapter to futures and I/O types.

Examples

Connect to an HTTP website, make a GET request, and pipe the response to the standard output:

There's a lot more in the examples directory.

Subcrates

  • async-channel - Multi-producer multi-consumer channels
  • async-executor - Composable async executors
  • async-fs - Async filesystem primitives
  • async-io - Async adapter for I/O types, also timers
  • async-lock - Async locks (barrier, mutex, reader-writer lock, semaphore)
  • async-net - Async networking primitives (TCP/UDP/Unix)
  • async-process - Async interface for working with processes
  • async-task - Task abstraction for building executors
  • blocking - A thread pool for blocking I/O
  • futures-lite - A lighter fork of futures
  • polling - Portable interface to epoll, kqueue, event ports, and wepoll

TLS certificate

Some code examples are using TLS for authentication. The repository contains a self-signed certificate usable for testing, but it should not be used for real-world scenarios. Browsers and tools like curl will show this certificate as insecure.

In browsers, accept the security prompt or use curl -k on the command line to bypass security warnings.

The certificate file was generated using minica and openssl:

Another useful tool for making certificates is mkcert.

License

Licensed under either of

  • Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
  • MIT license (LICENSE-MIT or #404)

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Issues

Collection of the latest Issues

bbros-dev

bbros-dev

0

We observe a stream of these errors:

when running rewrk --json -t 12 -c 500 -d 30s -h http://127.0.0.1:3000 against this simplified version of the examples/async-h1-server (with tls removed):

There are no build errors. We have found that if instead we use a smol::Executor these errors go away. Specifically, replace:

with:

We aren't sure if:

  • the example should just be updated,
  • we have used smol::spawn incorrectly
  • there is an issue with smol::spawn
YuhanLiin

YuhanLiin

0

The TLS example depends on async-native-tls, which has async-std as a dependency. I'm not sure how compatible smol is with libraries based on async-std, which is a whole other runtime. This also raises the question of whether futures-lite crates are compatible with futures-based crates, since the two use different Futures libraries. Even if compatibility isn't an issue, having async-std alongside smol will blow up compile times, which defeats the purpose of using smol in the first place. I suggest we use async_tls instead, since it doesn't depend on async-std or futures.

detly

detly

1

Here's a demo of using spawn() to run some timeouts:

It should print:

one
two
three
four

And exit (early, even) if you press Ctrl+C.

The docs for smol::spawn() say:

It is included in this library for convenience when writing unit tests and small programs, but it is otherwise more advisable to create your own Executor.

So I tried replacing smol::spawn with my own executor:

Now nothing is printed. Ctrl+C still works. I assume there is something else I have to do to get the executor working, but it's not documented what. The docs for Executor use something called easy_parallel which isn't part of smol.

System: rustc 1.49, Ubuntu 20.10, smol 1.2.5.

Ekleog

Ekleog

2

Hey! I just got tricked by #61, and checking the documentation wasn't that helpful: I was thinking that smol somehow had some kind of dark magic to make it work even though it was a file.

Reading #61 I understood what was wrong in my code (and I have been able to easily replace smol::Async with smol::Unblock), but to get to it I had to strace my process and figure out that the “permission denied” that was reported was due to epoll_ctl failing.

Hence, a suggestion: what would you think about making the documentation for Async::new and Unblock::new point to each other so people cannot miss the fact that the two exist and each cover their own ground?

ghost

ghost

5

We should have some traces in the reactor or executor

Sherlock-Holo

Sherlock-Holo

6

since async-std has used smol as the runtime, their TcpStream is a wrapper about Async<std::net::TcpStream>, that makes we can't use Async wrap it again and do something with read_with, write_with or use readable() and writable (which in PR #141).

If we can add a new method for Async<T> like

how to do this

In Unix we know in a process, if fd1 == fd2, that means both of them are referenced to the same thing, such as file description, socket, or anything else. So we can check Reactor if any Source has the same fd, if it exists, clone the Arc<Source> and return a new Async but references to the same fd.

I'm not good at Windows program but I see the RawSocket is a type alias for u64, so it maybe can work like in Unix.

ghost

ghost

3

copy-pasting some suggestions from @benmkw:

We still found it pretty challenging to dig though it. We found our way to the ThreadLokalExecutor and the ioEvent and the WorkStealingExecutor but the Reactor really puzzled us. We also did not really found how the waker is used. Like there are these three ways https://boats.gitlab.io/blog/post/wakers-i/ a waker can be implemented and the flag kind of seemed like it was the first of the three (which supposedly gets set by the OS), but then sending [1] onto the socket did not really make sense to us, like why is the executor writing to my own socket? Or no this has to be a signal that the OS sends to signal the executor that the future is ready? But why is it a socket then? Why is the writer a normal socket but the reader an Async? These were questions that we took into our minds to resolve in the future (after polling some more on them I guess ;) (Like when I’m talking about the OS im thinking of epoll/kqueue)

I think what would maybe help me is a kind of walk thought of execution from submitting a future to how its suspended, how the waker gets registered in the OS/ how the OS calls back into the executor to signal the future is ready to be polled again….

bugaevc

bugaevc

21

I would like to be able to use smol in software that already uses other runtimes. By that, I don't mean tokio or async-std; I mean completely different runtimes (usually called "I/O loops", "event loops" or "run loops") usually provided by an OS or by a toolkit. A few examples of such runtimes:

I'm not suggesting smol should add explicit support for each and every external runtime; I'm thinking of a more generic scheme, akin to what the Wayland event loop does (see wl_event_loop_get_fd() / wl_event_loop_dispatch() / wl_event_loop_dispatch_idle()).

The general idea is I would want the external runtime, rather than smol's reactor, to do the waiting on I/O part. Then, once some I/O can be performed on one of the file descriptors registered with smol, the external runtime would call back into smol, letting it handle the event.

This basically means smol should provide the API to get its epoll/kqueue fd (to be registered with the external event loop), and to "dispatch" events when the fd becomes readable (so, run its reactor & executor until it has nothing to do, then return instead of blocking).

joshtriplett

joshtriplett

15

I managed to run warp in smol, quite easily:

Please consider adding this as a demo.

ghost

ghost

enhancement
10

I'm assuming a browser (javascript) environment. Quick thoughts:

  • Async will be unusable because AsRawFd/AsRawSocket types don't exist on wasm.
  • Timer can be perhaps be implemented by calling setTimeout() in javascript.
  • Instead of running a thread-local or work-stealing executor, just spawn tasks through javascript.
  • Blocking executor should either be normal spawn or panic.

Information - Updated Jun 22, 2022

Stars: 2.4K
Forks: 124
Issues: 16

Repositories & Extras

Rust bindings for libinjection

Add libinjection to dependencies of Cargo

Rust bindings for libinjection

Rust bindings for the C++ api of PyTorch

LIghtweight wrapper for pytorch eg libtorch in rust

Rust bindings for the C++ api of PyTorch

Rust leveldb bindings

Almost-complete bindings for leveldb for Rust

Rust leveldb bindings

rust-analyzer is a modular compiler frontend for the Rust language

It also contains some tips &amp; tricks to help you be more productive when using rust-analyzer

rust-analyzer is a modular compiler frontend for the Rust language

Rust-Lightning is a Bitcoin Lightning library written in Rust

lightning, does not handle networking, persistence, or any other I/O

Rust-Lightning is a Bitcoin Lightning library written in Rust

Rust FUSE - Filesystem in Userspace

Rust library crate for easy implementation of Crate documentation

Rust FUSE - Filesystem in Userspace

Rust crate to implement a counterpart to the PBRT book's (3rd edition) C++ code:

Some images of the test scenes are shown below, but you can find more

Rust crate to implement a counterpart to the PBRT book's (3rd edition) C++ code:

Rust Persian Calendar

1** provides functionality for conversion among Persian (Solar Hijri) and Gregorian calendars

Rust Persian Calendar

P2P Rollback Networking in Rust

GGRS (good game rollback system) is a reimagination of the Rust 🦀

P2P Rollback Networking in Rust

Cardano Rust Ouroboros Network

This crate implements the networking layer for the Ouroboros blockchain protocol

Cardano Rust Ouroboros Network

An experimental project for using Golioth (currently just) on the nRF9160

This project is currently in a holding pattern until the Embedded Rust ecosystem has caught up to the necessary networking support

An experimental project for using Golioth (currently just) on the nRF9160

Painless peer-to-peer WebRTC networking for rust wasm applications

The goal of the Matchbox project is to enable udp-like, unordered, unreliable

Painless peer-to-peer WebRTC networking for rust wasm applications
Facebook Instagram Twitter GitHub Dribbble
Privacy