CASSGO-121 Improve host_source locking and ring refresh concurrency#1944
Conversation
worryg0d
left a comment
There was a problem hiding this comment.
Hey, I reviewed this patch - jfyi, I'm not an apache committer, so I'm just writing comments.
HostInfo methods might be on a hot path, so it is fine to narrow write-lock to read-lock where it is possible.
Having a benchmark would be useful to see the performance impact.
| mu sync.Mutex | ||
| prevHosts []*HostInfo | ||
| prevPartitioner string |
There was a problem hiding this comment.
I just realized they are never used
|
@worryg0d how set are you on having a comparison benchmark ? it's really out of my way and I'm struggling to make the time to do one. But since the change is trivial I figured it may not be a hard requirement, maybe ? |
|
This is not a hard requirement from my side - I assumed you have an application you can bench this change on, apologies if this is not the case. I'll review it one more time tomorrow to be sure we do not break anything. However, we will still need one more +1 from commiter. @joao-r-reis could you please take a look at this once you have a chance? |
worryg0d
left a comment
There was a problem hiding this comment.
LGTM +1
I created CASSGO-121 ticket for this.
@joao-r-reis, please take a look once you have a chance
|
friendly ping @joao-r-reis if you can spare the time to review this PR. |
|
@nanassito I'm not against making these changes but it feels like we're just doing them for the sake of doing them if we have no benchmark data to verify that these are actually improving the situation. We don't even have data to verify that the issue even exists in the first place... |
|
We can reopen this once we are provided with some data that helps us troubleshoot this potential issue |
|
yeah sorry @joao-r-reis we've got this fix in prod so it's quite a bit of work to get the comparison. I don't think it is worth my time to benchmark a comparison between a mutex and a rwmutex for something like this. |
|
And have you seen a measurable and noticeable impact caused by the changes contained in this PR? |
|
If you have these changes running in prod and you are able to notice an improvement then that is probably good enough for us to consider merging this in |
|
and to be fair, our workload is very silly in calling |
62dd5d5 to
9cf7e81
Compare
|
@joao-r-reis done, I think, please let me know if I did it wrong, this is my first commit on this particular project. |
|
changelog looks good, the commit message is still missing a line at the end like this:
|
|
I have already put my +1 here.
That's a huge improvement. Do you observe it with only this change to the driver? I guess it makes sense if you have a query observer that calls those methods, so narrowing to read lock unlocks queryExecutor.do() when it tries to pick a host to execute the query on. As Joao said, just add us as reviewers to the commit message, and we're good to merge it |
Remove ringDescriber mutex around GetHosts I/O; prevHosts/prevPartitioner were never written. Use read locks for ConnectAddressAndPort and a read-fast path for HostnameAndPort. Read peer validity under a single RLock in isValidPeer. Release errorBroadcaster mutex before sending to listeners. remove useless lock in isValidPeer Patch by Dorian Jaminais; reviewed by João Reis and Bohdan Siryk for CASSGO-121
|
oh my bad I thought you meant the github PR description instead of the git commit, updating now... |
9cf7e81 to
8ef7b8f
Compare
|
@joao-r-reis @worryg0d better ? |
|
Yeah looks good, just letting CI run then will merge, thanks! |



Use RWMutex instead of Mutex to guard fields in host_source
We discovered during a load test of one of our service that there is a lot of locking going on in
host_source.go. It turns out that a few can be optimized.Here are the set of changes in this PR:
1. ringDescriber / GetHosts
The mutex surrounded all of getLocalHostInfo and getClusterPeerInfo (control-connection I/O). prevHosts / prevPartitioner were never written anywhere, so error returns were always nil / "". The mutex only serialized unrelated ring refreshes for no benefit. Removed mu, prevHosts, and prevPartitioner, and return nil, "", err on failure so concurrent GetHosts no longer block each other on network work.
2. HostInfo.ConnectAddressAndPort
It only reads fields; it used Lock and blocked writers. Switched to RLock so it matches other read-only accessors.
This is the most costly one exposed by our load test.
3. HostInfo.HostnameAndPort
Uses a read-optimized path: RLock when hostname is already set (common case); Lock only when lazily filling hostname.
4. isValidPeer
Previously mixed RPCAddress() (under lock) with direct reads of hostId, dataCenter, etc. (racy). One RLock covers all fields and avoids extra lock cycles from a separate RPCAddress call.
5. errorBroadcaster.broadcast
Stopped holding the mutex while sending on listener channels (could stall other newListener / broadcast callers). Snapshot and clear listeners under the lock, then unlock and notify.
This has significantly improved the number of queries per cpu our workload can handle:

Patch by @nanassito ; reviewed by @joao-r-reis and @worryg0d for CASSGO-121