-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
core: Made ServerImpl.internalClose thread-safe. #11864
Conversation
Note: We are not following cancel calls as 2nd option (since option 2 is not feasible). Instead, we are allowing truncated messages in the stream and delivering the trailers. |
@@ -503,7 +503,7 @@ private void streamCreatedInternal( | |||
|
|||
final JumpToApplicationThreadServerStreamListener jumpListener | |||
= new JumpToApplicationThreadServerStreamListener( | |||
wrappedExecutor, executor, stream, context, tag); | |||
wrappedExecutor, executor, stream, context, tag, headers); |
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.
You need to create the trailers with metadata from the exception caught. See example.
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.
I agree that using these headers
is very wrong, as echoing back the client's request headers is harmful. Although, in fact, the original code was fine and it should just be a new set of Metadata. None of the callers of internalClose()
has metadata attached, and even if they do, we'd need to understand why a bit better because sending RST_STREAM was a valid way to handle this, which won't have metadata.
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.
Fixed
@@ -503,7 +503,7 @@ private void streamCreatedInternal( | |||
|
|||
final JumpToApplicationThreadServerStreamListener jumpListener | |||
= new JumpToApplicationThreadServerStreamListener( | |||
wrappedExecutor, executor, stream, context, tag); | |||
wrappedExecutor, executor, stream, context, tag, headers); |
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.
I agree that using these headers
is very wrong, as echoing back the client's request headers is harmful. Although, in fact, the original code was fine and it should just be a new set of Metadata. None of the callers of internalClose()
has metadata attached, and even if they do, we'd need to understand why a bit better because sending RST_STREAM was a valid way to handle this, which won't have metadata.
@@ -808,10 +824,9 @@ void setListener(ServerStreamListener listener) { | |||
/** | |||
* Like {@link ServerCall#close(Status, Metadata)}, but thread-safe for internal use. | |||
*/ | |||
private void internalClose(Throwable t) { | |||
// TODO(ejona86): this is not thread-safe :) | |||
private synchronized void internalClose(Throwable t) { |
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.
Throwing synchronized on it doesn't make it thread-safe. You'd have to synchronize most calls to the stream, and make sure to stop calling the stream after closing it. And we don't want to synchronize most calls to the stream. We will need help from the stream to implement this.
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.
Since all 3 callers of ServerImpl.closeInternal viz., onReady, messagesAvailable and halfClosed run serialized on the callExecutor, what makes the stream.close call in internalClose non-thread safe? Is the race with other methods on the stream?
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.
onReady, messagesAvailable, and halfClosed are callbacks and don't generally call into stream
(other than internalClose()
). You need to look for other calls into stream
. That would be from ServerCallImpl which is called by the application on arbitrary threads (but only one thread concurrently).
This is the "three threads" we had talked about for RPCs: application thread, transport thread, callback thread. stream
is used on the application thread, yet here we are using it from the callback thread (callExecutor).
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.
Fixed
Created the new PR with required changes and Addressed Review points in #11924. we will close this PR as duplicate once a new one merged. |
You could have added your commit on top of this PR itself. But it's fine now. |
I tried that and mentioned to you earlier in the tvc group as its Harsha's fork and don't have permission to push the changes. hence created the new branch/PR. |
Can we close this already if we are going to work with the new PR? |
Yes Kannan we can close this as a duplicate of PR #11924 which was raised earlier by Harsha. Even unable to close this PR as its Harsha's fork. Request you to close the same if you are able to see the same option or any other way to close it from the backend? |
core: Added changes to make ServerImpl.internalClose thread-safe and trigger cancel instead of completed.
Fixes #3746.