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.
> 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/S5TY3CRmsYOFun 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:
}
}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.
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.