4 ms·
If Go allowed something like "handle = go foo()", goroutine could be automatically terminated when handle goes out of scope or becomes dead and is garbage colle
by bakul 3y ago
If Go allowed something like "handle = go foo()", goroutine could be automatically terminated when handle goes out of scope or becomes dead and is garbage collected. You can also use handle to cancel a goroutine etc.
Go designers specifically avoided this model (of having a goroutine "id") for reasons I don't remember any more (may be to avoid making them heavier weight?) but this would be one way to stop leaky goroutines.
- atombender 3y agoIt's because just terminating a goroutine isn't safe with respect to I/O and defer chains. I think Go has the internal plumbing to theoretically support this, though it might require inserting checks more often. Another way would be to make contexts first-class and automatically insert context checks even when not done (e.g. selects). And also all I/O has to be cancellable. I suspect Go's designers prefers the current way in which cancellation is explicit.
- bakul 3y ago> just terminating a goroutine isn't safe with respect to I/O and defer chains. Agreed. The idea is to panic() if a goroutine has to be forcibly terminated due to GC, instead of a slow leak. Requires more thought though.
- masklinn 3y agoSo the idea is to randomly take down the program when the GC runs?
- bakul 3y agoLet me try to explain. The current way (which must continue working the same way even if the language is changed) does not allow you to distinguish a goroutine that should terminate but hasn't due to some bug versus a goroutine that can legitimately run for a long time. Making the goroutine "id" explicit can allow you distinguish the two cases. Store the id in some global or long lived variable or array if you want the goroutine to run for a long time. Otherwise carefully control the scope of such an id so that the runtime has a chance to catch the first case. That is my initial thinking but it would need to be fleshed out more. For instance, there should be a way to test that goroutine has terminated. Currently you do this explicitly by passing a channel and waiting for a message.
- dagss 3y agoThe Go way is to pass the long running goroutines a different ctx from the short running. Or even one ctx per goroutine and cancel them dynamically according to whatever logic.
- ikiris 3y agoIf you actually code in go there, they expect you to handle it yourself though by not orphaning goroutines. Err groups or similar will take care of this. Basically it's people writing bad code because they can. There's already options to handle it available.
- dagss 3y agoThe convention of passing ctx does almost the same thing though. Make a new context.WitCancel and pass it to the goroutine. It just requires programmer cooperation, but as long as you pass ctx all through the stack down and handle err on the way back, it is not often you deal with it explicitly.
- silisili 3y agoIt does, but feels extremely bolted on(because it was). To do properly , near every single function and method has to take a context, which gets repetitive. Then every single thing in the call stack needs to actually check for cancellation. It feels like something similar should be baked in, and inherited from its parent by default(but overrideable). And a cancel would cancel the callstack. Would be nice to make this cleaner in go 2, I think.