There is good news, though! Rust is a powerful language when it comes to encouraging robust code through warnings and compile-time errors, and we can take advantage of that. Here's how... 10/29
-
Show this thread
-
Let's replace JoinHandle<T> with a new type simply called Task<T> that is very similar except it also acts like a guard that cancels the task when dropped. Task<T> is an awaitable future that resolves to a value of type T, which is the task's result. 11/29
2 replies 0 retweets 6 likesShow this thread -
When a task is cancelled, it gets immediately woken and the next time the executor takes it out from the task queue, it will be simply dropped. Automatic cancellation is one of the core tenets of structured concurrency. 12/29
1 reply 0 retweets 3 likesShow this thread -
Task<T> is also marked with #[must_use], so if you accidentally drop it without ever using it, the compiler warns you. That aligns closely with how futures typically work - dropping a future implies its cancellation. 13/29pic.twitter.com/dqAI9mWFUY
1 reply 0 retweets 6 likesShow this thread -
If you want to keep the task running in the background with no strings attached, forget() its Task<T> handle. 14/29pic.twitter.com/USMwYCt1pL
2 replies 0 retweets 2 likesShow this thread -
But here's the catch: you can only forget() tasks that resolve to (), which means you can't accidentally forget() a task that resolves to a Result or some other type. Now spawn(process(stream)) doesn't even compile - problem solved! 15/29
2 replies 0 retweets 9 likesShow this thread -
The compiler now requires us to unwrap results in spawned tasks. But it'd be nice to have some API sugar here that is not as verbose as this... 16/29pic.twitter.com/YB7eLhDSgh
1 reply 0 retweets 2 likesShow this thread -
What if there were unwrap() and expect() methods on Task<Result<T,E>> that transform it into Task<T> and panic on error? Those methods spawn a new task that simply unwraps the result and returns the success value. 17/29pic.twitter.com/7eQfRDqSN8
1 reply 0 retweets 2 likesShow this thread -
Now we can do spawn(process(stream)).unwrap().forget(), which is pretty nice! This is what the entire TCP echo server looks like in my new runtime I'm working on. 18/29pic.twitter.com/H9Z2Nm9TOJ
3 replies 0 retweets 11 likesShow this thread -
Replying to @stjepang
I was wondering about how the Async type works internally, as you said in another thread it is only a wrapper around anything Read + Write, so in definitive it can't use the power of poll/kqueue/select and every Async type must but used in a given thread or something?
2 replies 0 retweets 1 like
The Async type is a wrapper around types that implement AsRawFd or AsRawSocket, and it hooks their file descriptors into epoll/kqueue (on Unixes) or raw sockets into WSAPoll (on Windows). It's all conceptually pretty simple, and I will reveal the trick soon!
-
-
Replying to @stjepang
Ho that's nice! I thought the Async types one worked on Read + Write types but there is a little bit more! Thank you for those really interresting Twitter threads
That's everytimes a pleasure to read, please continue!0 replies 0 retweets 1 likeThanks. Twitter will use this to make your timeline better. UndoUndo
-
Loading seems to be taking a while.
Twitter may be over capacity or experiencing a momentary hiccup. Try again or visit Twitter Status for more information.