Resolve various races in QPS sync client#13576
Conversation
|
|
|
|
|
|
|
|
1 similar comment
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The flakes on this PR have nothing to do with QPS testing. This is ready to review. |
kpayson64
left a comment
There was a problem hiding this comment.
Do you mind adding a quick comment in the PR description as to the nature of the races (Handle Shutdown before initialization should be fine if I understand this correctly).
Also what do you think about changing the cleaner lambda to a overrideable function? Feel free to say "lambda's are lit, get with the times old man".
test/cpp/qps/client_sync.cc
Outdated
| cleanup_threads.emplace_back([this, i, cleaner]() { | ||
| std::lock_guard<std::mutex> l(stream_mu_[i]); | ||
| if (stream_[i]) { | ||
| shutdown_[i].val = cleaner(&context_[i], stream_[i].get()); |
There was a problem hiding this comment.
I'm a little confused by this. What happens if stream is not initialized by the time we call OnAllStreams? Then shutdown would never get set. It looks like this PR addresses a race condition where we shutdown before we finish initialization, but if looks like its impossible for that to happen.
There was a problem hiding this comment.
Good point, I guess that case wasn't happening yet in practice. I've resolved this.
test/cpp/qps/client_sync.cc
Outdated
| cleanup_threads.emplace_back([this, i, cleaner]() { | ||
| std::lock_guard<std::mutex> l(stream_mu_[i]); | ||
| if (stream_[i]) { | ||
| shutdown_[i].val = cleaner(&context_[i], stream_[i].get()); |
There was a problem hiding this comment.
It looks like all the lambdas return true. Can we just assign shutdown_[i].val = true for simplicity? (I was confused by what happens if the cleaner fails at first).
There was a problem hiding this comment.
Sounds good. My original intention was to make this a general map-operation-on-stream but there is no need for such generality now (or possibly ever). Changed.
|
I've also edited the PR description with details about the races being resolved and changed the lambdas to a virtual function. I was originally resistant about doing that because the base class |
|
1 similar comment
|
|
Wait, my last change was dumb. I should have tested it locally first, will fix. |
|
|
|
I've changed my mind. Lambdas are lit. This is ready for re-review. I think the new form of the lambdas is better. |
|
|
|
1 similar comment
|
|
|
Again, no QPS-related flakes! |
Fixes #13122 and various related issues
This resolves several different kinds of races in the QPS sync client:
DestroyMultithreading(which is called before the client has to shutdown) rather than at the client destructor. Test cases such asstreaming_from_servercould end up getting stuck forever otherwise if a client thread was still doing a Read op and could never escape it to do the thread join, creating a deadlockAdditionally, this PR refactors a common code path by which a "cleanup" operation is applied to all streams at different points.