5 ms·
Yes, properly handling timeouts and cancellation is the next frontier for programmers to conquer. I was just thinking about this the other day because some pro
by jrockway 7y ago
Yes, properly handling timeouts and cancellation is the next frontier for programmers to conquer. I was just thinking about this the other day because some program I was using locked up, and of course it worked fine when restarted, and I began to wonder why this happens so frequently. A lot of obscure things can cause hangs, but if every blocking operation has a timeout, the number goes way down.
I think it's unfortunate that even new languages still treat timeouts and cancellation as an afterthought. For example, every Go program I've ever written says:
select {
case <-ctx.Done():
return nil, ctx.Err()
case thing := <-thingICareAboutCh:
return thing, nil
}
Instead of:
return <-thingICareAboutCh, nil
The language designers thought about needing to give up on blocking operations, and then said "meh, let the programmer decide on a case-by-case basis". And that's the state of the art.
(Getting off topic, this is why I avoid mutexes and other concurrency operations that aren't channels; you can't cancel your wait on them. Not being able to cancel something means that if there are any bugs in your program, you'll find out when the program leaks thousands of goroutines that are stuck waiting for something that will never happen and runs out of memory. Even if the thing they're waiting for does happen, the browser that's going to tell someone about it has long been closed, and so you'll just die with a write error when you finally generate a response. If you have a timeout and a cancellation on every blocking task, your program gives up when the user gives up, and will run unattended for a lot longer.)
- noelwelsh 7y agoGo is very much not the state of the art in anything. It's really based on 1980s ideas.
- gpderetta 7y agomore like 60s: Go vs Brand X [1] [1] http://cowlark.com/2009-11-15-go/ http://cowlark.com/2009-11-15-go/
- pornel 7y agoI like how Rust handles cancellations. Async is polling based. If you stop polling and drop the Future object, it's cancelled. All of it. Like in the library from the article, every await point is a point where an async task can end.
- laumars 7y ago> this is why I avoid mutexes and other concurrency operations that aren't channels; you can't cancel your wait on them Mutexes are designed to solve different problems -- albeit with overlap. Channels are great if you have a one to one relationship or even a many to one but they're not so good with many to many relationships. That is where you need several routines to have read access and several routines to have write. I'm not saying they can't be used in that way but if you're not careful it's even easier to have goroutines "stuck waiting for something that will never happen" with channels than it is with mutexes. So I'd be very nervous about shoehorning channels into a design they're not well suited for. Also you can cancel your wait on mutex if there is another goroutine which unlocks that mutex. In fact if you browse the Go source you'd see that channels use mutexes themselves.
- foota 7y agoDecent mutexes do support a timeout?
- notriddle 7y agoPOSIX's does: https://linux.die.net/man/3/pthread_mutex_timedlock https://linux.die.net/man/3/pthread_mutex_timedlock So does parking_lot: https://docs.rs/lock_api/0.3.2/lock_api/struct.Mutex.html#method.try_lock_until https://docs.rs/lock_api/0.3.2/lock_api/struct.Mutex.html#me...