Rune has first class support for Rust-like asynchronous programming. In this section we'll be briefly covering what asynchronous programming is, and how it applies to Rune as a dynamic programming language.
Asynchronous code allows us to run multiple tasks concurrently, and work with the result of those tasks.
A typical example would be if we want to perform multiple HTTP requests at once:
{{#include ../../scripts/book/async/async_http.rn}}
$> cargo run --bin rune -- run scripts/book/async/async_http.rn
200 OK
200 OK
In the above code we send two requests concurrently. They are both processed at the same time and we collect the result.
A fundamental construct of async programming in Rune is the select
block.
It enables us to wait on a set of futures at the same time.
A simple example of this is if we were to implement a simple request with a timeout:
{{#include ../../scripts/book/async/async_http_timeout.rn}}
$> cargo run --bin rune -- run scripts/book/async/async_http_timeout.rn
200 OK
Request timed out!
But wait, this is taking three seconds. We're not running the requests concurrently any longer!
Well, while the request and the timeout is run concurrently, the request
function is run one at-a-time.
To fix this we need two new things: async
functions and .await
.
async
functions are just like regular functions, except that when called they
produce a Future
.
In order to get the result of this Future
it must be .await
ed. And .await
is only permitted inside of async
functions and closures.
{{#include ../../scripts/book/async/async_http_concurrent.rn}}
$> cargo run --bin rune -- run scripts/book/async/async_http_concurrent.rn
Result: 200 OK
Request timed out!
Closures can be prefixed with the async
keyword, meaning calling them will
produce a future.
{{#include ../../scripts/book/async/async_closure.rn}}
$> cargo run --bin rune -- run scripts/book/async/async_closure.rn
Status: 200 OK
Blocks can be marked with async
to produce on-the-fly futures. These blocks
can capture variables the same way as closures do, but take no arguments.
{{#include ../../scripts/book/async/async_blocks.rn}}
$> cargo run --bin rune -- run scripts/book/async/async_blocks.rn
Status: 200 OK