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

Breaking: Get rid of atomic cancellation and provide a replacement #1937

Merged
merged 46 commits into from Oct 12, 2020

Conversation

elizarov
Copy link
Contributor

@elizarov elizarov commented Apr 22, 2020

This is problematic for Android when Main dispatcher is cancelled on destroyed activity. Atomic nature of channels was designed to prevent loss of elements, which is really not an issue for a typical application, but creates problem when used with channels. Atomic cancellation for channel is replaced with the "prompt cancellation guarantee".

Fixes #1813 (explains the problem in detail)
Fixes #1265
Fixes #1915
Fixes #1936

This is a problematic for Android when Main dispatcher is cancelled on destroyed activity.
Atomic nature of channels is designed to prevent loss of elements,
which is really not an issue for a typical application, but creates problem when used with channels.

* Internal suspendAtomicCancellableCoroutine -> suspendCancellableCoroutine
* Internal suspendAtomicCancellableCoroutineReusable -> suspendCancellableCoroutineReusable
* Remove atomic cancellation from docs
* Ensures that flowOn does not resume downstream after cancellation.
* MODE_ATOMIC_DEFAULT renamed into MODE_ATOMIC
* Introduced MODE_CANCELLABLE_REUSABLE to track suspendCancellableCoroutineReusable
* Better documentation for MODE_XXX constants.
* Added stress test for proper handling of MODE_CANCELLABLE_REUSABLE
  and fixed test for #1123 bug with job.join (working in MODE_CANCELLABLE) that was not
  properly failing in the absence of the proper code in CancellableContinuationImpl.getResult
* Added test for Flow.combine that should be fixed
* Support extended invokeOnCancellation contract
* Introduced internal tryResumeAtomic

Fixes #1265
Fixes #1813
Fixes #1915
@elizarov elizarov changed the title [DRAFT] Get rid of atomic cancellation and provide a replacement Get rid of atomic cancellation and provide a replacement Sep 16, 2020
@elizarov elizarov changed the title Get rid of atomic cancellation and provide a replacement Breaking: Get rid of atomic cancellation and provide a replacement Sep 16, 2020
Co-authored-by: Louis CAD <louis.cognault@gmail.com>
@qwwdfsad
Copy link
Member

qwwdfsad commented Oct 5, 2020

I still have 20% performance regression on this particular benchmark: ChannelSinkBenchmark.channelPipelineOneThreadLocal. What's the source of it?

Copy link
Member

@qwwdfsad qwwdfsad left a comment

Choose a reason for hiding this comment

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

Please take a look at benchmarks one more time

elizarov and others added 13 commits October 5, 2020 18:21
Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
* It must drain the channel before trying to verify.
* A detailed analysis on failure is printed.
This makes code cleaner, highlighting the fact that the actual resumeMode is always set when the continuation is being resumed.
+ added explicit test to ensure that a regular suspendCoroutine from stdlib resumes atomically and ignores cancellation.
Also, assert mode is MODE_CANCELLABLE_REUSABLE, don't update it.
@elizarov
Copy link
Contributor Author

elizarov commented Oct 7, 2020

Update w.r.t benchmarks. With this commit 164d3e5 the memory allocation rate (in bytes per op) on the ChannelSinkBenchmark.channelPipelineOneThreadLocal is now the same as it is in the main branch of the code. However, it is still slower.

@qwwdfsad qwwdfsad self-requested a review October 12, 2020 15:19
Copy link
Member

@qwwdfsad qwwdfsad left a comment

Choose a reason for hiding this comment

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

Great! Good to go 🚀

@elizarov elizarov merged commit 8773a26 into develop Oct 12, 2020
@elizarov elizarov deleted the resource-cancel branch October 12, 2020 16:09
recheej pushed a commit to recheej/kotlinx.coroutines that referenced this pull request Dec 28, 2020
…otlin#1937)

This is a problematic for Android when Main dispatcher is cancelled on destroyed activity.
Atomic nature of channels is designed to prevent loss of elements,
which is really not an issue for a typical application, but creates problem when used with channels.

* Internal suspendAtomicCancellableCoroutine -> suspendCancellableCoroutine
* Internal suspendAtomicCancellableCoroutineReusable -> suspendCancellableCoroutineReusable
* Remove atomic cancellation from docs
* Ensures that flowOn does not resume downstream after cancellation.
* MODE_ATOMIC_DEFAULT renamed into MODE_ATOMIC
* Introduced MODE_CANCELLABLE_REUSABLE to track suspendCancellableCoroutineReusable
* Better documentation for MODE_XXX constants.
* Added stress test for proper handling of MODE_CANCELLABLE_REUSABLE
  and fixed test for Kotlin#1123 bug with job.join (working in MODE_CANCELLABLE) that was not
  properly failing in the absence of the proper code in CancellableContinuationImpl.getResult
* Added test for Flow.combine that should be fixed
* Support extended invokeOnCancellation contract
* Introduced internal tryResumeAtomic
* Channel onUnderliveredElement is introduced as a replacement.

Fixes Kotlin#1265
Fixes Kotlin#1813
Fixes Kotlin#1915
Fixes Kotlin#1936

Co-authored-by: Louis CAD <louis.cognault@gmail.com>
Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
recheej pushed a commit to recheej/kotlinx.coroutines that referenced this pull request Dec 28, 2020
…otlin#1937)

This is a problematic for Android when Main dispatcher is cancelled on destroyed activity.
Atomic nature of channels is designed to prevent loss of elements,
which is really not an issue for a typical application, but creates problem when used with channels.

* Internal suspendAtomicCancellableCoroutine -> suspendCancellableCoroutine
* Internal suspendAtomicCancellableCoroutineReusable -> suspendCancellableCoroutineReusable
* Remove atomic cancellation from docs
* Ensures that flowOn does not resume downstream after cancellation.
* MODE_ATOMIC_DEFAULT renamed into MODE_ATOMIC
* Introduced MODE_CANCELLABLE_REUSABLE to track suspendCancellableCoroutineReusable
* Better documentation for MODE_XXX constants.
* Added stress test for proper handling of MODE_CANCELLABLE_REUSABLE
  and fixed test for Kotlin#1123 bug with job.join (working in MODE_CANCELLABLE) that was not
  properly failing in the absence of the proper code in CancellableContinuationImpl.getResult
* Added test for Flow.combine that should be fixed
* Support extended invokeOnCancellation contract
* Introduced internal tryResumeAtomic
* Channel onUnderliveredElement is introduced as a replacement.

Fixes Kotlin#1265
Fixes Kotlin#1813
Fixes Kotlin#1915
Fixes Kotlin#1936

Co-authored-by: Louis CAD <louis.cognault@gmail.com>
Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants