3 ms·
Did you see the examples? Even with the blocking threaded style the Java versions gave me nightmares. And they didn't even bring up a cancelation example (not 1
by klabb3 5y ago
Did you see the examples? Even with the blocking threaded style the Java versions gave me nightmares. And they didn't even bring up a cancelation example (not 100% sure on that). Cancelation and subsequent graceful shutdown is one of the hardest concurrency problems that (a) you are very likely to need in practice and (b) conveniently often are left out of example code. Heck it isn't even great in Go (too explicit imo) but at least they solved it.
- emccue 5y agoCan you elaborate more? All of the parts that throw `InterruptedException` are handling the thread interrupt cancelation mechanism. There is also the example with the atomic boolean quit flag. I'm not convinced that Go has any unique mechanisms here. Just like Java you can't forcefully kill a thread without that thread's cooperation.
- mperham 5y agoGo provides a context package which allows in-flight cancellation of heavy operations spanning processes and even machines. https://pkg.go.dev/context https://pkg.go.dev/context
- emccue 5y agoOkay this is cool. I think mechanically the plans for ScopeLocals can be a part of implementing a scheme like that. Either way - I need to read this thoroughly in the morning.
- mkdirp 5y agoThis is also part of how you could interrupt `time.Sleep`. > In Go there is less noise, but also there no way to interrupt Go's time.Sleep. The full piece would be something like: func sleepCtx(ctx context.Context, delay time.Duration) { select { case <-ctx.Done(): case <-time.After(delay): } } func main() { fmt.Printf("%v\n", time.Now()) ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) defer cancel() sleepCtx(ctx, 1*time.Second) fmt.Printf("%v\n", time.Now()) } Runnable example on Go playground: https://go.dev/play/p/S5TY3CRmsYO https://go.dev/play/p/S5TY3CRmsYO
- klabb3 5y agoYep this is a utility function in sure thousands have written, including myself. It's not in std which is weird but go had been a bit inconsistent since context was a big api change. Fun fact: that func has a hidden bug, if one should be pedantic. Can you spot it?
- eadmund 5y ago> Fun fact: that func has a hidden bug, if one should be pedantic. Can you spot it? Are you referring to the fact that the timer is still hanging around? Would this be the most-correct version? func sleepCtx(ctx context.Context, delay time.Duration) { t := time.NewTimer(delay) defer func() { if !t.Stop() { <-t.C } }() select { case <-ctx.Done(): case <-t.C: } }
- klabb3 5y ago[Weird, I remember already replying to this comment.] Yes that's what I was thinking of :) I'm a bit unsure what's the value in draining the channel (which is internal to this func), given that Go should garbage collect channel (and in this case perhaps even some escape analysis). EDIT: Ah they aren't just closing the channel, but sending a time.Time. That makes sense, the timer wouldn't have anyone to send to if it's unbuffered.