For audioserve update I wanted use new hyper
with tokio-tls
. Actually it required a bit of documentation reading, but finally turned our quite straightforward.
Tag Archives: asynchronous I/O
First Impressions about New Rust Async
Just recently async
and await
made it to stable version of Rust. futures
library 0.3 is also out and rest of other important libraries is following – for me tokio
and hyper
are particularly interesting. tokio
is now in alpha stage supporting new futures, so I decided it’s about a time to give it a try. Some time ago I’ve rewritten ptunnel in Rust using 0.1 version of tokio
and futures
. So here are my first experiences with new libraries and upgrade.
Future Is A State Machine
I think I noticed in this article that Rust Future is basically a state machine, which is propagated through its states via appropriate runtime (and parked when not ready to move to a next state). But I did not appreciate this fact fully until recently I was making a small utility (here is new version for new futures and tokio) for creating tar archive asynchronously – it should be a Stream that produces chunks of data – first file header and then pieces of it’s content. When file is done move to next file, until all required files are sent to stream, then finally send two empty blocks, each of 512 bytes of binary zeros. I needed this Stream for my audioserve project, where I wanted to download content of whole directory as a tar archive. Stream is a kind of Future (which produces many values instead of just one), so it’s also a state machine. And when I started to think about it this way, implementation was obvious. Rust algebraic type system is of great help here as we can represent state with one complex enum type ( called TarState in this case) and it’s variants represent states of this state machine and also contain necessary internal variables for each state. So lets see state diagram for our TarStream: Continue reading Future Is A State Machine
From Ignorance to Enlightenment – Playing with Tokio
I have been playing with tokio already in couple of small projects (ptunnel-rust and indirectly (via hyper) in audioserve), but I cannot say that I’m proficient. Also tokio is very much moving target – what I used couple month ago is already bit outdated now(old version is tokio_core crate – where default executor was on current thread, now it’s work stealing thread pool). So I decided to refresh and deepen my knowledge and created a toy project – stupid jokes server – it’s a TCP sever, which sends a random joke to client after it connects and then closes connection. Jokes are stored in text file, separated by dashed lines. My main interest was to test how to use local file system I/Os, which are blocking by nature, with tokio asynchronous approach (so I initially skipped easiest and probably most efficient implementation, where all jokes would be cached in memory). Usually in a real project you’ll have some blocking code, so I need to know how to handle it. This article is history of my attempts (and failures) recorded in a hope that it might help others in learning tokio (and also writing it down helped me to absorb gained knowledge). Continue reading From Ignorance to Enlightenment – Playing with Tokio
Asynchronous Again – Rewriting ptunnel in Rust
Asynchronous programing model is quite popular for I/0 intensive tasks – it enables you effective use of resources, while maintaining agility of and assuring scalability of the application. I myself used asynchronous programming many times – in JavaScript (where it’s omnipresent) , Python ( mainly in asyncio recently, but also bit in twisted, which was one of first network asynchronous libraries I met) and also in OCAML with lwt or Core Async. The concept is always similar for all implementations – I/O operations are returning handles to future results – they are called either Futures, Promises, or Deferred – and they are returned immediately. These futures can have functions attached to them, which are executed later, when I/O result becomes available. Asynchronous programming is very much about functions, it requires first class functions and anonymous functions are very useful here, that’s why asynchronous model flourishes in functional languages. Apart of I/O deferred processing usually there are other utilities for later execution – like timeouts, pausing execution for some time (sleep), tasks synchronization (events, locks). Futures are executed in an “event loop”, a loop that monitors various events from OS (availability of data from I/O), timers, etc. to execute futures (meaning functions attached to them), when appropriate. It’s also very common to chain futures, executing second one with result of first one , when first one is resolved and result is available and the third one with results from the second one and so on. Apart of this basic scheme languages may provide some syntactic sugar around asynchronous model like await and async keywords in Python or C#, which makes it easier to write the code.
Recently, as I’m progressing in learning of Rust, I wondered how asynchronous programing is done in Rust. I decided to remake my old project ptunnel (written in Python) into Rust – ptunnel is a program that tunnels arbitrary connection/protocol through HTTPS proxy, so it can be used to connect IMAP, SMTP or SSH through proxy. In the rest of this article I”l share my experiences from this project. Continue reading Asynchronous Again – Rewriting ptunnel in Rust