4 ms·
Show me how to cancel a network requests using only threads, with no access to the underlying socket APIs? Because that's trivial with `async`. That's not "fun
by insanitybit 3y ago
Show me how to cancel a network requests using only threads, with no access to the underlying socket APIs? Because that's trivial with `async`.
That's not "fun", that's table stakes.
- losvedir 3y agoTotal rust newb here, but does that need the full async story, or is it a limitation of an API somewhere? From the point of view of the code using the request's response could you use a channel with recv_timeout? Is the problem there that the thread with the socket connection is still going and there's no way to stop it?
- insanitybit 3y agoThe ability to cancel an operation without talking to the operating system requires that your program has yield points. That yielding is what allows another part of the program to take control and say "OK, I'm done with you now, no need to finish". Yes, the problem is that your thread would continue to perform work even if you stopped waiting on it.
- vc8f6vVV 3y agoMaybe I don't understand the complexity, but in good old Ruby I can easily stop a thread if I don't need result anymore. No async needed and no yield points necessary. Doesn't it apply to Rust too?
- insanitybit 3y agoI assume that Ruby does in fact have yield points in some form, such as a global lock. Killing a thread is only possible (for a pthread) via the `pthread_cancel` API. That API is very dangerous and is generally not something you'd ever want to use manually - the thread will not clean up any memory or other resources, any shared memory is left in a tricky state. To gracefully shut a thread down you need yielding of some kind.
- klabb3 3y ago> Show me how to cancel a network requests using only threads, with no access to the underlying socket APIs? It’s been a long time since I did this in Rust. But why do you not have access to the sockets or at least a set_timeout method? Is it a higher level lib that omits such crucial features? In Go, the super common net.Conn interface has deadline methods. Not everyone knows their importance but generally you have something like it piped through to the higher layers. EDIT: Oh I see you replied to my other comment. Please disregard.
- Matthias247 3y agoYou can cancel socket operations using signals. You can eg have one or more background threads running timers which will interrupt the blocking IO if it doesn’t return in a timely manner. A lot of very important frameworks and services that are used in billions of transactions per day use this model.
- insanitybit 3y agoOf course you can. It does mean that you need cooperation between the child and parent thread (to set up the signal handler so that resources are cleaned up) though. That's easy in a framework, kind of a pain in the ass if you're just trying to get some opaque client you were passed to do something in <10 seconds. And that's just for IO. I mentioned elsewhere that you may want to cancel pure compute work. You can see my point, I assume, that when your userspace program can cancel tasks natively it's much easier to work with?
- vc8f6vVV 3y agoCan you cancel a tight computing loop (i.e. without system calls and without yielding of any sort) with async? I wonder how? Also if you can inject a cleanup code in your async task what prevents you from doing it with threads? Such things existed long before async/await and system calls didn't change for async/await. Also, what's the difference between "framework" and async/await runtime, isn't the latter a kind of a framework?
- Matthias247 3y agoThe last comment is actually pretty interesting and spot on. In the Java/JDK world - which you can assume as a „framework“ - you can cancel blocking IO via the Thread.interrupt() mechanism. And that works because it’s deeply integrated into the framework, similar like async Rust runtimes provide support for cancellation.
- deleted 3y ago[deleted]