nhooyr.io/websocket v1.8.10
The library uses defer defer wg.Wait() in multiple functions and that causes calls to deadlock instead of properly shutting down when connection is terminated.
One possible situation is this:
- The server calls
CloseRead
- The Client sends some message
- Goroutine in
CloseRead unblocks from Reader(ctx) and calls Close
Close blocks on defer c.wg.Wait() but it can't succeed due to CloseRead calling wg.Add(1) and expecting it to be decremented with defer wg.Done() on exit from CloseRead. But CloseRead cannot exit due to Close blocking. We have a deadlock and a goroutine leak. Context is never cancelled either which means all the other code that interacts with websocket also can't properly exit.
Switching to manually calling Read in a separate goroutine and cancelling context from it solves this problem. Basically, you have to reimplement CloseRead but without blocking on waitGroup
nhooyr.io/websocket v1.8.10
The library uses defer
defer wg.Wait()in multiple functions and that causes calls to deadlock instead of properly shutting down when connection is terminated.One possible situation is this:
CloseReadCloseReadunblocks fromReader(ctx)and callsCloseCloseblocks ondefer c.wg.Wait()but it can't succeed due toCloseReadcallingwg.Add(1)and expecting it to be decremented withdefer wg.Done()on exit fromCloseRead. ButCloseReadcannot exit due toCloseblocking. We have a deadlock and a goroutine leak. Context is never cancelled either which means all the other code that interacts with websocket also can't properly exit.Switching to manually calling
Readin a separate goroutine and cancelling context from it solves this problem. Basically, you have to reimplementCloseReadbut without blocking on waitGroup