Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix panic() in internal/connection when writing to a closed channel d…
…uring close The race is as follows: T1 - calls SendRequestNoWait(), checks the connection state, and prepares to enter the select statement T2 - calls TriggerClose() closes cnx and the closeCh T3 - run() go-routine for processing incomingRequestsCh drops into case <-closeCh: and calls failLeftRequestsWhenClose() which drains and closes incomingRequestsCh T1 - resumes and drops into the select where both closeCh and incomingRequestsCh are closed. When two cases of a `select` are valid, the case executed is chosen at random; see https://tour.golang.org/concurrency/5 This commit introduces a connectionClosing state and a wait group to track writes by the SendRequest() methods. * TriggerClose() moves the connection into the connectionClosing state before the closeCh is closed. * The failLeftRequestsWhenClosed() method waits on the waitgroup for outstanding SendRequest() methods to complete before it closes the incomingRequestsCh * The SendRequest() methods first add to the waitgroup before checking the connection state; if the state is either closing or closed, SendRequest() returns an error. With the above it is not possible for thread to attempt to add a request to the incomingRequestsCh without being tracked by the waitgroup, and the incomingRequestsCh will not be closed until operations tracked by the waitgroup have completed. Signed-off-by: Daniel Ferstay <dferstay@splunk.com>
- Loading branch information