Skip to content
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

Fix wrong exceptions being thrown on send failure. #8084

Merged
merged 3 commits into from
Sep 19, 2016

Conversation

jtattermusch
Copy link
Contributor

Tentative fix for #7223.

origTcs.SetException(new InvalidOperationException("Send failed"));
if (!delayCompletion)
{
origTcs.SetException(IsClient ? GetRpcExceptionClientOnly() : new IOException("Error sending from server."));
Copy link
Contributor

@apolcyn apolcyn Sep 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we only fill in the exception for the SendMessageTask here if the final call completion handler has already been ran through, meaning the GetRpcExceptionClientOnly will always be able to fill in with a non-null FinalStatus? Maybe use a sort of invariant if so? Got caught here for a little bit with the delayCompletion flag

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you understand that correctly, but you are right that the code was a bit cryptic. I tried to improved that by adding a precondition and some comments.

@jtattermusch
Copy link
Contributor Author

Addressed the comments, PTAL.

Copy link
Contributor

@apolcyn apolcyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple comments for questions/clarifying how I'm understanding the change is working, please correct me if I'm wrong on these.

// The write will wait for call to finish to receive the status code.
Assert.IsFalse(writeTask.IsCompleted);

fakeCall.UnaryResponseClientHandler(true,
Copy link
Contributor

@apolcyn apolcyn Sep 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the StatusCode.Internal being the made up status core will create?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

TaskCompletionSource<object> origTcs = null;
lock (myLock)
{
origTcs = streamingWriteTcs;
streamingWriteTcs = null;

if (!success && !finished && IsClient)
{
// We should be setting this only once per call, following writes will be short circuited.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They get short circuited later only because the next call can't start until the current one, which waits on the final status, is complete?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, good question. There was a problem with the implementation - because streamingWriteTcs was reset here, if there was a delayed write completion, one could have started another write even though the failed write hasn't finished yet from user's perspective (and that also meant that the statement in the comment was incorrect).

I changed the implementation to use a boolean flag isDelayedStreamingWriteCompletion and I'm leaving streamingWriteTcs set until the call actually finishes. Now everything should be alright hopefully. I also added a test that was exposing the issue with the implementation (it is passing now).

PTAL. Hopefully no more fixes will be needed.

@apolcyn
Copy link
Contributor

apolcyn commented Sep 16, 2016

LGTM for changes in last two commits

@jtattermusch jtattermusch merged commit c4f9c9a into grpc:master Sep 19, 2016
@lock lock bot locked as resolved and limited conversation to collaborators Jan 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants