Sans-IO: The secret to effective Rust for network services
1–10 of 89 posts
Re: Sans-IO: The secret to effective Rust for network services
#2Re: Sans-IO: The secret to effective Rust for network services
#3Why would you want this in a client? It's not like a client needs to manage tens of thousands of connections. Unless it's doing a DDOS job.
Re: Sans-IO: The secret to effective Rust for network services
#4Good job! Exposing state could make any async function 'pure'. All the user needs to do is push the state machine to the next state. I have tried to bind OpenSSL to async Rust before, its async API follows a similar design.
Is the similarity you are seeing that the work itself that gets scheduled via a job is agnostic over how it is executed?
From this example [0] it looks more like that async API is very similar to Rust's futures:
- Within a job you can access a "wait context"
- You can suspend on some condition
- You can trigger a wake-up to continue executing
[0]: https://www.openssl.org/docs/man1.1.1/man3/ASYNC_is_capable....
Re: Sans-IO: The secret to effective Rust for network services
#5"... be it from your Android phone, MacOS computer or Linux server. " Why would you want this in a client? It's not like a client needs to manage tens of thousands of connections. Unless it's doing a DDOS job.
The main benefit is being able to use `&mut` everywhere: At the time when we read an IP packet from the TUN device, we don't yet know, which gateway (exit node), it needs to go to. We first have to look at the user's policies and then encrypt and send it via a WireGuard tunnel.
Similarly, we need to concurrently receive on all of these tunnels. The tunnels are just a user-space concept though. All we do is receive on the UDP socket and index into the corresponding data structure based on the sending socket.
If all of these "connections" would use their own task and UDP socket, we'd would have to use channels (and thus copying) to dispatch them. Additionally, the policy state would have to be in an `Arc` because it is shared among all connections.
Re: Sans-IO: The secret to effective Rust for network services
#6Good job! Exposing state could make any async function 'pure'. All the user needs to do is push the state machine to the next state. I have tried to bind OpenSSL to async Rust before, its async API follows a similar design.
I did some quick research and found that there is an "async job" API in OpenSSL. That one appears to do IO though, it even says that creating a job is a very expensive operation and thus jobs should be reused. Is the similarity you are seeing that the work itself that gets scheduled via a job is agnostic over how it is executed? From this example [0] it looks more like that async API is very similar to Rust's futures…
Re: Sans-IO: The secret to effective Rust for network services
#7"... be it from your Android phone, MacOS computer or Linux server. " Why would you want this in a client? It's not like a client needs to manage tens of thousands of connections. Unless it's doing a DDOS job.
Re: Sans-IO: The secret to effective Rust for network services
#8Earlier quoted context omitted.
I did some quick research and found that there is an "async job" API in OpenSSL. That one appears to do IO though, it even says that creating a job is a very expensive operation and thus jobs should be reused. Is the similarity you are seeing that the work itself that gets scheduled via a job is agnostic over how it is executed? From this example [0] it looks more like that async API is very similar to Rust's futures…
Yes, you're right. It's not entirely similar, it's not IO-less. But in async Rust (or any other stackless coroutine runtimes), IO should be bound to the scheduler. This allows IO events callback scheduler and wake the task it binds to. Exposing and manually pushing state is a good way to decouple IO from the scheduler.
It is possible to do the same blocking IO but it feels a little less natural: You have to set the read-timeout on the socket to the time when you need to wake-up the state machine.
[0]: https://github.com/firezone/sans-io-blog-example/blob/99df77...
Re: Sans-IO: The secret to effective Rust for network services
#9The biggest productivity boost to my rust embedded firmware development was when I could stop manually implementing state machines and marshalling all local variables into custom state after custom state between each I/O operation snd let rust do that for me by using async/await syntax!
That’s, after all, what async desugars to in rust: an automatic state machine that saves values across I/O (await) points for you.
Re: Sans-IO: The secret to effective Rust for network services
#10I got half way through this article feeling like this pattern was extremely familiar after spending time down inside rust-libp2p. Seems like that wasn't a coincidence!
Firezone looks amazing, connect all the things!