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
-
Show 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 -
Replying to @Kerollmops @stjepang
What I am saying is that if the Async struct can accept anything Read + Write wihtout knowing the internal type it cannot force the type to be nonblocking or anything, and it cannot ask for the rawsocket to use it in any system polling function (poll/kqueue/select).
1 reply 0 retweets 1 like
The Async::nonblocking() constructor that converts a T into Async<T> requires you to promise that T has been set into non-blocking mode. Take a look at this implementation of Async<UdpSocket>::bind() to see how that works in practice.pic.twitter.com/qKcOgUA29G
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.