-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Improve handling of DispatchException in an undispatched case #4272
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
Conversation
Looking at #4209 (comment), I have yet to see an elegant, generalized solution to our problem that is neither a breaking change nor an obvious contract breach |
|
||
private fun ScopeCoroutine<*>.dispatchException(e: DispatchException) { | ||
makeCompleting(CompletedExceptionally(e.cause)) | ||
throw throw recoverStackTrace(e.cause, uCont) |
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.
One throw
should be enough.
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 wanted to be extra-sure the exception is thrown
return cause !is TimeoutCancellationException || cause.coroutine !== this | ||
} | ||
|
||
private fun ScopeCoroutine<*>.dispatchException(e: DispatchException) { |
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 think this function should be inlined. It's not obvious that it calls makeCompleting
.
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 am, in general, for the opposite approach -- get rid of all "very uncommon" cases from a code path that is supposed to be followed. I renamed the function and changed return type to be Nothing
for the readability sake
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.
Do you have examples of where this approach improves code clarity? My intuition is that this only works in backend-like applications where you let all errors bubble up as exceptions and then just restart the request.
My approach 95% of the time is that a function must be a non-leaky abstraction: it hides the details that are not important to you, but doesn't hide the details that are. dispatchExceptionAndMakeCompleting
is not an abstraction, the name is a (non-compiler-verified) enumeration of what it does. If the idea is to use as little space as possible for this codepath, we can join the two statements with ;
.
import org.junit.runners.model.TestTimedOutException | ||
import java.util.concurrent.TimeoutException |
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.
Are these imports used?
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.
Nope. Fixed
} | ||
|
||
private fun ScopeCoroutine<*>.dispatchException(e: DispatchException) { | ||
makeCompleting(CompletedExceptionally(e.cause)) |
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.
Why not makeCompletingOnce
, to highlight the aspects of this codepath that are different from the happy path?
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 would like this path to be as robust as possible. There might be obscure reasons for DispatchException
, for example a dispatcher sent coroutine to execute and then failed in the post-send code-path.
makeCompletingOnce
can throw, and I would like to avoid extra try-catches here to preserve the contextual information (i.e. the suppressed dispatch exception)
fun testFlowOn() { | ||
// See #4142, this test ensures that `coroutineScope { produce(failingDispatcher, ATOMIC) }` | ||
// rethrows an exception. It does not help with the completion of such a coroutine though. | ||
// Hack to avoid waiting for test completion |
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.
Where's the hack?
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.
Made the comment more straightforward
f8503e4
to
8389768
Compare
| Package | Type | Package file | Manager | Update | Change | |---|---|---|---|---|---| | [org.jetbrains.kotlinx:kotlinx-coroutines-test](https://github.com/Kotlin/kotlinx.coroutines) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `1.10.1` -> `1.10.2` | | [org.jetbrains.kotlinx:kotlinx-coroutines-slf4j](https://github.com/Kotlin/kotlinx.coroutines) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `1.10.1` -> `1.10.2` | | [org.jetbrains.kotlinx:kotlinx-coroutines-core](https://github.com/Kotlin/kotlinx.coroutines) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `1.10.1` -> `1.10.2` | | [software.amazon.awssdk:sdk-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | | [software.amazon.awssdk:sqs](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | | [software.amazon.awssdk:dynamodb-enhanced](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | | [software.amazon.awssdk:dynamodb](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | | [software.amazon.awssdk:aws-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | | [software.amazon.awssdk:bom](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | | [software.amazon.awssdk:auth](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.31.16` -> `2.31.17` | --- ### Release Notes <details> <summary>Kotlin/kotlinx.coroutines (org.jetbrains.kotlinx:kotlinx-coroutines-test)</summary> ### [`v1.10.2`](https://github.com/Kotlin/kotlinx.coroutines/blob/HEAD/CHANGES.md#Version-1102) [Compare Source](Kotlin/kotlinx.coroutines@1.10.1...1.10.2) - Fixed the `kotlinx-coroutines-debug` JAR file including the `module-info.class` file twice, resulting in failures in various tooling ([#​4314](Kotlin/kotlinx.coroutines#4314)). Thanks, [@​RyuNen344](https://github.com/RyuNen344)! - Fixed `Flow.stateIn` hanging when the scope is cancelled in advance or the flow is empty ([#​4322](Kotlin/kotlinx.coroutines#4322)). Thanks, [@​francescotescari](https://github.com/francescotescari)! - Improved handling of dispatcher failures in `.limitedParallelism` ([#​4330](Kotlin/kotlinx.coroutines#4330)) and during flow collection ([#​4272](Kotlin/kotlinx.coroutines#4272)). - Fixed `runBlocking` failing to run its coroutine to completion in some cases if its JVM thread got interrupted ([#​4399](Kotlin/kotlinx.coroutines#4399)). - Small tweaks, fixes, and documentation improvements. </details> --- ### Configuration 📅 **Schedule**: Branch creation - "after 6pm every weekday,before 2am every weekday" in timezone Australia/Melbourne, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Never, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). GitOrigin-RevId: 3449fc325ac14573dff5b670e407e99eab23757b
No description provided.