Closed kskitek closed 1 year ago
Thanks for fixing this @kskitek. I'm looking at this and considering the different approaches and seeing if there is a better way. If I don't find anything we'll merge this. Thanks.
Hey @kskitek sorry for the delay. This client was for a while needing a refactoring so I went ahead and made https://github.com/signalfx/signalfx-go/pull/198 that will be a new v2 module. I incorporated your goroutine check and have completely reworked how shutdown happens to hopefully avoid any leaks and make the client generally more robust.
@benkeith-splunk Thank you for the fix! I like the changes in the reworked client. It will probably take us some time but we will migrate to v2.
Problem
When the connection is not established (for example due to the wrong realm)
Client.Close()
leaves goroutines behind.While testing, I have spawned 33 clients and closed 32 - this should leave me with just 2 goroutines but I have 34 instead.
Details
signalflow.NewClient
spawns two goroutines:Client.run
wsConn.Run
Client.Execute
is called by the userClient.sendMessage
and waits inserializeAndWriteMessage
on one of:c.conn.OutgoingTextMessages() <- &outgoingMessage
return <-resultCh
Solution
Fix closing of the client
wsConn.Run
can:OutgoingTextMessages
to unblockClient.serializeAndWriteMessage
nil
error tooutgoingMessage.resultChan
to unblockClient.serializeAndWriteMessage
wsConn.outgoingMessage
to unblock shutting down inwsConn.run
Refactor
NewClient
I didn't take this path - random thoughts of other changes to fix the situation.
Testing
The scenario can be tested manually by:
client.ExecuteProgram
client.Close
I have provided a test
Test_Close_DoesNotLeakGoroutines
that simulates this situation and compares how many goroutines are before and after the test.