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.
As much as I love Java (I co-founded Apache Java), golang is a great fit for this usecase.
Total boot payload is about 160megs... which I need to do some more work on... I think I can get this down to about 120megs, but it hasn't been a priority yet since this is working well enough for now. About 54megs of that boot is just some third party drivers and right now, those are .gz encoded... need to switch to xz to bring it down.
I presume it would have to be because there is no guarantee that the JVM will be installed and configured exactly correctly on all of those machines a priori.
Jlink helps solve that problem if you have a properly modularized project, but that's hard to do if your dependencies aren't also properly modularized.
The Go version needs that executable, nothing else.
In the same way that golang is bundling a GC implementation... except it is orders of magnitude smaller than a JVM.
It is a fresh language and i quite enjoyed exploring it, but i just can't see the use of it. (also, the multiple return value functions are great, but if only there was a way to use a particular value directly from the function without having to assign them to variables)
And I'm hardly a fan of Go.
There is room enough for both languages.
So all what left is opinionated in-language support vs library support, and it is not clear cut which is the winner. Java seems to allow finer control over the primitives of concurrency, so a library or another JVM language could build up a much better abstraction over the mechanism.
But I really hope that the new, record-based, minimal boilerplate java style gets hyped up more and more, we really should prefer compile time metaprogramming instead of reflection-based solutions. (E.g. mapstruct is really cool!)
Still closer though, and GraalVM native images are pretty cool.
https://mail.openjdk.java.net/pipermail/discuss/2020-April/0...
Or as a type safe C for userspace.