Skip to content

Recover cancellation when close responses flow #344

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

Merged
merged 2 commits into from
Jul 27, 2022

Conversation

akandratovich
Copy link
Contributor

When streaming call is cancelled it's handled in sender coroutine (lines 311-319). Both client call cancellation (line 316) and failure propagation (line 317) eventually reach the listener onClose callback (where responses flow is closed), but which one reaches the place first is racy. When failure propagation reaches the callback first, the flow is cancelled with cancellation exception (expected). But if the client call cancel reaches the callback first, the flow is cancelled with GRPC status exception (unexpected).

This change recovers the cancellation from GRPC status exception if it was the cause to make the behavior deterministic and aligned with expectations.

I don't know how to test this change reliably. I succeeded to reproduce the issue via slow emulator tests only with some chance over 100+ runs.

@akandratovich
Copy link
Contributor Author

There is a failing test that asserts that flow fails with grpc error if request flow throws CancellationException. Is it part of the contract? The similar java test asserts on RuntimeException.

@jamesward
Copy link
Collaborator

That is a question for @lowasser

@lowasser
Copy link
Collaborator

lowasser commented Jul 6, 2022

It seems reasonable to delete that test, I don't think it should be part of the contract.

@akandratovich
Copy link
Contributor Author

I have "removed" the test.

… cancelled it's handled in `sender` coroutine (lines 311-319). Both client call cancellation (line 316) and failure propagation (line 317) eventually reach the listener `onClose` callback (where `responses` flow is closed), but which one reaches the place first is racy. When failure propagation reaches the callback first, the flow is cancelled with cancellation exception (expected). But if the client call cancel reaches the callback first, the flow is cancelled with GRPC status exception (unexpected). This change recovers the cancellation from GRPC status exception if it was the cause to make the behavior deterministic and aligned with expectations. I don't know how to test this change reliably. I succeeded to reproduce the issue via slow emulator tests only with some chance over 100+ runs.
@jamesward jamesward merged commit 0681fc8 into grpc:master Jul 27, 2022
@akandratovich akandratovich deleted the patch-1 branch July 28, 2022 08:46
@bubenheimer bubenheimer mentioned this pull request Feb 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants