← Back to context

Comment by tommiegannert

1 year ago

> Further, goroutines' lack of their stack ancestry means they can't natively give out the nice stacktraces found in other languages,

There's GODEBUG=tracebackancestors=N since 2018.

https://pkg.go.dev/runtime

> 3. Goroutine b panics, crashing the program. > > 4. The database connection is then left open as a zombie TCP connection. > > [---] Because of this stack disconnection of parents and children, it really becomes impossible to have exceptions.

I don't follow this reasoning. If goroutine b panics, the process dies and the TCP connection is closed by the OS. If you handle the panic in b, there's no zombie connection, since both a and b are still alive to handle the connection.

Exceptions are just return statements with pattern matching on stack unwind. Nothing special. I can't figure out what the author sees in them that I don't. The Go defer statements are perfectly capable of handling lifetimes, and a common situation is that you create a goroutine just to manage a resource's lifetime, e.g. when you have multiple producers and you need to close the channel after all of them are done.

> In Go, only calls made by the offending goroutine can recover from a panic, while in Java, the parent caller/creator of the new thread can itself set a recovery mechanism.

And in Go, the caller can insert a stub function that handles recovery before calling the main goroutine function. This seems equivalent to me.

> He says the mainframers at his company hate UnixODBC for this reason, it tends to leave zombie connections behind. (Go uses UnixODBC

I don't know how his dad's mainframe handles terminated processes, but this needs clarification on why they're left: the OS really should take care of closing those connections.

> Consider the problem of a task scheduler cancel button. The program must schedule a task to be run on an agent. At any given time, however, the task must be able to be cancelled.

Fair enough, that requires extra adaptation to Go (what the author calls workarounds.) It will never be as nice as simply killing a preemptive thread.

> In Java, it is child's play to interrupt a running thread.

And now the application programmer has to handle far more cases of partially complete tasks instead. The number of strawman arguments in this post is astounding.