The things you didn't know about async Rust
Learn async Rust
Do you remember a time when you learned something so quickly because you had an afternoon to experiment and a way to find out whether something worked? Riding a bike? Solving a puzzle? Learning to cook?
The publisher Manning has created something like that - but for tech and over the last couple of months I have been working on a Manning LiveProject for async Rust. The testers liked what I built, so I wanted to share it with you.
This format is a guided learning experience with challenges and milestones where you create a small(ish) project that actually does something. Similar to what you’d do if you created some project in your free time, the idea is to provide the space and help required to push your Rust abilities to the next level.
Note that it’s guided learning, so you’ll get access to Manning resources or read up on topics using the provided links to learn by doing. If there are any questions - I’ll be there as a mentor to respond to your posts, as well as the other learners whom you could connect with.
In the case of my LiveProject, it comes with a somewhat over the top story (or is it?!):
In this liveProject, you’ll use some of the unique and lesser-known features of the Rust language to finish a prototype of a FinTech command line tool. You’ll step into the shoes of a developer working for Future Finance Labs, an exciting startup that’s aiming to disrupt mortgages, and help out with building its market-tracking backend. Your CTO has laid out the requirements for the minimum viable product, which must quickly process large amounts of stock pricing data and calculate key financial metrics in real time.
Technically it’s two projects bundled togehter (or available individually, your choice), so which could be right for you? I tired for both to be a provide practical insights and considerations of using Rust to create something that is much better than the regular hello world type tutorial.
Data Streaming with Async Rust
This project is all about transforming a synchronous Rust project to async
. This means creating tests, making sure everything runs concurrently as it should, and using the right frameworks to achieve that goal.
Without giving away too much, here’s an example. This unit test has to be transformed into async
:
#[test]
fn test_MinPrice_calculate() {
let signal = MinPrice {};
assert_eq!(signal.calculate(&[]), None);
assert_eq!(signal.calculate(&[1.0]), Some(1.0));
assert_eq!(signal.calculate(&[1.0, 0.0]), Some(0.0));
assert_eq!(
signal.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0]),
Some(1.0)
);
assert_eq!(
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]),
Some(0.0)
);
}
… so it turns into this:
#[async_std::test]
async fn test_MinPrice_calculate() {
let signal = MinPrice {};
assert_eq!(signal.calculate(&[]).await, None);
assert_eq!(signal.calculate(&[1.0]).await, Some(1.0));
assert_eq!(signal.calculate(&[1.0, 0.0]).await, Some(0.0));
assert_eq!(
signal.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0]).await,
Some(1.0)
);
assert_eq!(
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]).await,
Some(0.0)
);
}
Simple? Do you know why those changes are necessary and what they actually do? In that case, you should check out the second project in the series.
Advanced Data Streaming With Async Rust
Building on the first project (the required code will be provided), you’ll find the second project to be somewhat different. In reliable large scale data processing, the actor model has become very popular since it enables easy concurrency and distributed processing. The most popular framework in this area is Akka - but what about building such a system in Rust?
Actors are already big in Rust, since the most popular web framework - actix-web - builds on actix, an actor framework. These frameworks take away the details of how streams of data (or messages) get from one place in the code to the other. Instead it lets the developer focus on what the code is acutally trying to achieve: build a machine learning system, create a big data processing pipeline, or simply use I/O as efficiently as possible.
This LiveProject provides you with an opportunity to play around with different aspects of an actor system. The solution I built is based on xactor, which is easy to use and builds on async_std. However if you already know actix, you can (and should) try and solve the challenges with it.
Here is an example actor that you will build:
#[message]
#[derive(Debug, Clone)]
struct QuoteRequest {
symbol: String,
from: DateTime<Utc>,
to: DateTime<Utc>
}
pub struct StockDataDownloader;
#[async_trait::async_trait]
impl Handler<QuoteRequest> for StockDataDownloader {
async fn handle(&mut self, _ctx: &mut Context<Self>, msg: QuoteRequest) {
// Process a QuoteRequest message here
}
}
Admittedly, actors are a bit exotic at first - but they are everywhere if you look closely. Microsoft’s ServiceFabric is running half of Azure and uses actors extensively, Akka mentions several case studies on their website on how their customers use the framework, and lastly the Erlang programming language is the actor model’s biggest success story.
What else?
I suggest the LiveProjects for anyone who wants to spend 1-2h a day (for a week) to get hands-on experience with Rust. I had fun creating the challenges and I am sure you will have fun going through the challenges. For anyone who considers themselves fairly new to Rust and async
- check out the first LiveProject, it sits right above the first couple of tutorials.
The second project is geared towards more experienced (intermediate?) Rust developers who want to play a little more with different approaches and frameworks. In my mind, the LiveProject is just as much a place to experiment as it is to learn - and according to science we use play to learn best!
Either way, you’ll end up with a usable Rust program in the end that reads stock data from Yahoo Finance, but it could easily read something else - crypto prices from an exchange such as Kraken, for example …
Lastly, the obvious disclaimer: each sale generates royalties for me, but I don’t depend on them and I create content because it‘s fun and helps people. Look out for discounts and other sales for more affordable prices or use the many free Rust resources - I’m happy to help out with that.