4 ms·
> When timeout is implemented in async/await variant of the solution, using the `driver.race(timeout).await`, what happens to the client socket after the `race`
by f_devd 3y ago
> When timeout is implemented in async/await variant of the solution, using the `driver.race(timeout).await`, what happens to the client socket after the `race` signals the timeout error?
Any internal race() values will be `Drop`ed and driver itself will remain (although rust will complain you are not handling the Result if you type it 'as is'), if a new socket was created local to the future it will be cleaned up.
The niceness of futures (in Rust) is that all the behavior around it can be defined, while "all functions are blocking." as you state in a sibling comment, Rust allows you to specify when to defer execution to the next task in the task queue, meaning it will poll tasks arbitrarily quickly with an explicitly held state (the Future struct). This makes it both very fast (compared to threads which need to sleep() in order to defer) and easy to reason about.
Java's Thread.interrupt is also just a sleep loop, which is fine for most applications to be fair. Rust is a system language, you can't have that in embedded systems, and it's not desirable for kernels or low-latency applications.
- avodonosov 3y ago> Java's Thread.interrupt is also just a sleep loop You probably mean that Java's socket reading under the hood may start a non-blocking IO operation on the socket, and then run a loop, which can react on Thread.interrupt() (which, in turn, will basically be setting a flag). But that's an implementation detail, and it does not need to be implemented that way. It can be implemented the same way as async/await. When a thread calls socket reading, the runtime system will take the current threads continuation off the execution, and use CPU to execute the next task in the queue. (That's how Java's new virtual threads are implemented). Threads and async/await are basically the same thing. So why not drop this special word `async`?
- f_devd 3y ago> So why not drop this special word `async`? You can drop the special word in Rust it's just sugar for 'returns a poll-able function with state'; however threads and async/await are not the same. You can implement concurrency any way you like, you can run it in separate processes or separate nodes if you are willing to put in the work, that does not mean they equivalent for most purposes. Threads are almost always implemented preemptively while async is typically cooperative. Threads are heavy/costly in time and memory, while async is almost zero-cost. Threads are handed over to the kernel scheduler, while async is entirely controlled by the program('s executor). Purely from a merit perspective threads are simply a different trade-off. Just like multi-processing and distributed actor model is.
- gpderetta 3y ago> Threads are almost always implemented preemptively while async is typically cooperative. Threads are heavy/costly in time and memory, while async is almost zero-cost. Threads are handed over to the kernel scheduler, while async is entirely controlled by the program('s executor). Keyword here being almost. See Project Loom.
- Ygg2 3y agoJava can afford that. M:N threads come with a heavy runtime. Java has already a heavy runtime, so what is a smidgen more flab? Source: https://github.com/rust-lang/rfcs/blob/master/text/0230-remove-runtime.md https://github.com/rust-lang/rfcs/blob/master/text/0230-remo...
- gpderetta 3y agoSo it seems that the biggest issue was having a single Io interface forcing overhead on both green and native threads and forcing runtime dispatching. It seems to me that the best would have been to have the two libraries evolve separately and capture the common subset in a trait (possibly using dynamic impl when type erasure is tolerable), so that you can write generic code that can work with both or specialized code to take advantage of specific features. As it stand now, sync and async are effectively separated anyway and it is currently impossible to write generic code that hande both.
- avodonosov 3y ago@f_devd, cooperative vs preemptive is a good point. (That threads are heavy or should be scheduled by OS is not required by the nature of the threads). But preemptive is strictly better (safer at least) than cooperative, right? Otherwise, one accidental endless loop, and this code occupies the executor, depriving all other futures from execution. @gpderetta, I think Project Loom will need to become preemptive, otherwise the virtual threads can not be used as a drop-in replacement for native threads - we will have deadlocks in virtual threads where they don't happen in native threads.