-
Notifications
You must be signed in to change notification settings - Fork 3.9k
core: Added changes to make ServerImpl.internalClose() thread-safe #11924
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
base: master
Are you sure you want to change the base?
Changes from all commits
bd1749b
2d76254
24350ad
2ba2ca9
9ee6878
bd71484
16bd7e9
feed5a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,7 @@ protected interface Sink { | |
private final StatsTraceContext statsTraceCtx; | ||
private boolean outboundClosed; | ||
private boolean headersSent; | ||
private boolean closeCalled; | ||
|
||
protected AbstractServerStream( | ||
WritableBufferAllocator bufferAllocator, StatsTraceContext statsTraceCtx) { | ||
|
@@ -120,6 +121,7 @@ public final void deliverFrame( | |
|
||
@Override | ||
public final void close(Status status, Metadata trailers) { | ||
Preconditions.checkState(!closeCalled, "call already closed"); | ||
Preconditions.checkNotNull(status, "status"); | ||
Preconditions.checkNotNull(trailers, "trailers"); | ||
if (!outboundClosed) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If internalClose was called before, outboundClosed would have been set to true and any further calls to close() from anywhere else already skips over if outboundClosed is true. Your changes here don't seem to be achieving anything extra. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to make the check apply for usages of stream in ServerCallImpl (application thread usages of the stream) if the stream had already been closed. Refer comment. Also we should not need to add another field to track the stream closed status since there is already an outboundClosed field and this should be able to be used for such checks. |
||
|
@@ -130,6 +132,7 @@ public final void close(Status status, Metadata trailers) { | |
// closedStatus is only set from here, and is read from a place that has happen-after | ||
// guarantees with respect to here. | ||
transportState().setClosedStatus(status); | ||
closeCalled = true; | ||
abstractServerStreamSink().writeTrailers(trailers, headersSent, status); | ||
} | ||
} | ||
|
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.
Is precondition the right thing to do or will logging an error message do? With an example callstack for close
Failed precondition will cause the exception to be caught at
runInContext:861, ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed
and again callinternalClose
and rethrow the exception which then will be caught and logged inrun:133, SerializingExecutor
.If the application continues to attempt to write messages these steps will keep repeated for each attempt and the application is not going to come to know of it anyway. It may be better to just write an error log instead. @ejona86 to confirm.