-
Notifications
You must be signed in to change notification settings - Fork 18
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
Fix broadcast data races #151
Fix broadcast data races #151
Conversation
Address data races between: * HasListeners and any other method using Lock() * Broadcast and Close Switch to a RWMutex for finer-grained locking.
For further details, here's some snapshots of the data races I can produce with the first commit 83abad0: HasListeners() and Close() (any mutation of b.subscribers would do)
Broadcast() and Close()
|
Hi @JohnStarich , thank you for the contribution, this looks good. I will take a deeper look at this next week. Filed internally as 244791. |
9b387be
into
launchdarkly:cw/sc-244791/broadcast-data-race
Hi @JohnStarich , I've merged this PR into a feature branch prior to merging to the main branch. I made an additional set of changes here: #152. Please review when able. |
Thanks for taking a look! Reviewed! |
This has been released in https://github.com/launchdarkly/go-server-sdk/releases/tag/v7.4.1. Please file another issue if you have any other problems. Thanks! |
Requirements
Related issues
I hit data races when running tests in parallel, which effectively obscures other data races my application may have. It looks like others did too, judging by #102.
Fixes #102
Describe the solution you've provided
I've addressed 2 data races with improved locking:
HasListeners()
had a data race due to any mutation onb.subscribers
Close()
had a data race where closing a send channel triggers a panic inBroadcast()
I also saw an easy opportunity to use more fine-grained locks with an RWMutex, although I'm happy to back that out if you would prefer.
Describe alternatives you've considered
I also considered using an atomic data type for subscribers, but I figured that change would be less of a surgical fix. It also may be more difficult to mutate the slice, since a compare-and-swap can fail and would need a loop (it's not as simple as
atomic.Add
).Another idea which may be simpler is using a channel to manage shutdown. Typically I'd use a
context.Context
here to manage cancellation. That'd also preventBroadcast()
ing on a full send channel from blockingClose()
.Additional context
Add any other context about the pull request here.