fix: Shut down zombie goroutine in chronicleexporter #2029
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Proposed Change
While testing another fix by spinning up a chronicle exporter, sending a log to Chronicle, and then shutting down the exporter, I encountered this error:
I was understandably confused, so asked for help from Dan Jaglowski, and he figured it out and came up with this solution after hours, along with some other refactors. Explanation and fix are all his, I'm just opening the PR.
To fix this, the Shutdown function actually needs to be:
Larger explanation:
In Start, when we instantiate the httpClient : ce.httpClient = oauth2.NewClient(context.Background(), creds.TokenSource) , it doesn't actually matter what context we pass in. It isn't used for cancelation.
What we get back is always an *http.Client that contains a Transport field of type *oauth2.Transport. This in turn always contains a Base that is nil, which means it will use http.DefaultTransport. The thing with http.DefaultTransport (as well as many others) is that they will reuse connections by setting them into a "keep alive" state. The only way to clean these up is to call CloseIdleConnections() on the Transport. However, because we're getting an *oauth2.Transport that doesn't itself contain a CloseIdleConnections() method, we have to to access the http.DefaultTransport directly and call CloseIdleConnections() on it.
If you would like a test case to reproduce this, please contact me for one - not sure we have one that doesn't involve actually sending data to Chronicle.
Checklist