-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Event loop leaks intervals #81
Comments
The root cause here is that there is no mechanism to "dispose" the loop. When you stop it, it is expected that it would be restarted at some point and will be running until it finishes all its tasks. Implementing it would require some considerable refactoring, like the loop would need to keep references to all intervals and times so that it could clear them all and clearing intervals would need to be done in a different way to avoid the situation you've described. Note, even if it's all done it wouldn't help the issue from #80, there you need to keep track of the channel and close it after stopping the loop. |
I am hopeful that the refactoring is not that complicated. for {
ctx, cancel := context.WithCancel(context.Background())
loop := eventloop.NewEventLoop(eventloop.WithContext(ctx))
loop.Start()
interval := loop.SetInterval(func(vm *goja.Runtime) {}, 10*time.Millisecond)
time.Sleep(500 * time.Millisecond)
loop.ClearInterval(interval) // not strictly necessary
loop.Stop() // not strictly necessary
cancel()
fmt.Println(runtime.NumGoroutine())
} |
…nts further job submission. Closes #81
How about this? |
That looks better, having the advantage of waiting for job completion on termination - while I don't really need this (in my case, if the loop takes over 10 seconds to |
…nts further job submission. Closes #81
Consider the following case:
Expectation: the number of running goroutines doesn't really increase.
Reality: the printed number keeps increasing...
I suspect, but I am not entirely sure, that this happens because in
eventloop/eventloop.go
, there might be a race that leaves interval goroutines waiting forever:Consider the case where both stopChan and ticker.C have a message, the select will choose "randomly" between them and it might choose the second case. I think, but am not entirely sure because I haven't fully analyzed the code, that the send into jobChan might block when the loop is stopped. There's also the possibility that the loop is stopped precisely after entering the ticker.C case and before jobChan is fed, in any case, in my production service I have identified lingering goroutines waiting to send into jobChan past the moment all event loops are stopped. Because the interval callback has access to the goja runtime, this effectively means that together with the leaked goroutine, the runtime and all of its globals will live in memory forever...
The text was updated successfully, but these errors were encountered: