-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Ensure we send all Stream messages in a single go routine #15266
Ensure we send all Stream messages in a single go routine #15266
Conversation
Signed-off-by: Manan Gupta <[email protected]>
Review ChecklistHello reviewers! 👋 Please follow this checklist when reviewing this Pull Request. General
Tests
Documentation
New flags
If a workflow is added or modified:
Backward compatibility
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #15266 +/- ##
==========================================
+ Coverage 67.45% 67.47% +0.01%
==========================================
Files 1560 1560
Lines 193203 193224 +21
==========================================
+ Hits 130324 130373 +49
+ Misses 62879 62851 -28 ☔ View full report in Codecov by Sentry. |
Signed-off-by: Manan Gupta <[email protected]>
I don't quite like this fix. The bug we're seeing is clearly a corner case, because it's been very hard to diagnose, so it's not happening consistently. It's not a generalized issue because the scatter code in the planner tries to use locking where necessary to ensure we're not returning results concurrently. Hence, changing all response writes to go through a channel is just a fixed amount of unnecessary overhead which we should not pay for. The right fix is figuring out exactly which of the plan primitives is sending this data concurrently and adding synchronization there, without forcing serialization on all the other primitives which are already serialized. @harshit-gangal and @systay have already gone down this path before because we found a few routes that had concurrent races and we fixed them. I'm sure they have thoughts here. |
Hello! 👋 This Pull Request is now handled by arewefastyet. The current HEAD and future commits will be benchmarked. You can find the performance comparison on the arewefastyet website. |
ss := newStreamSender() | ||
ss.start(stream) | ||
defer ss.close() | ||
|
||
session, vtgErr := vtg.server.StreamExecute(ctx, nil, session, request.Query.Sql, request.Query.BindVariables, func(value *sqltypes.Result) error { | ||
// Send is not safe to call concurrently, but vtgate | ||
// guarantees that it's not. | ||
return stream.Send(&vtgatepb.StreamExecuteResponse{ | ||
resp := &vtgatepb.StreamExecuteResponse{ | ||
Result: sqltypes.ResultToProto3(value), | ||
}) | ||
} | ||
return ss.sendMessage(resp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vtgate always sends a single stream of responses. It is protected by the mutex in executor
which is above any engine primitive. So, we do not need this streaming protection here.
Description
This PR fixes the issue pointed out in #14760 (comment) after following up on #14939 (review).
The proposed fix is to create a new struct that ensures that all the stream messages are sent from a single go routine. Tests have also been added to ensure that everywith works as intended.
Related Issue(s)
Checklist
Deployment Notes