-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Introduce deprecated coroutine builder overloads accepting a Job #4435
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: develop
Are you sure you want to change the base?
Conversation
This is a small step towards deprecating the practice of breaking structured concurrency by passing a `Job` to a coroutine builder. See #3670
Awesome stuff! |
* throw IllegalStateException("$it is tired of all this") | ||
* } | ||
* } | ||
* coroutines.joinAll() |
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 do an explicit join here? supervisorScope
should wait for its children, right?
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.
Yes, it will. The idea was to highlight how joinAll
will not fail in this scenario, but this piece of documentation may not be a good place for that.
* scope.async(start = CoroutineStart.ATOMIC) { | ||
* withContext(NonCancellable) { | ||
* // this line will be reached even if the parent is cancelled | ||
* } | ||
* // note: the cancellation exception *can* be thrown here, | ||
* // losing the computed value! | ||
* } |
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.
Does that mean you can loose the value, even if there is no code after the withContext
block?
scope.async(start = ATOMIC) {
withContext(NonCancellable) {
dontWantToLooseThisResource()
}
// no code here, or only code without suspension points
}
The documentation for withContext
says there will be no cancellation on entry/exit with NonCancellable
.
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.
My comment is misleading, but yes, the value can be lost, just not because of withContext
. The problem is that if the Deferred
is cancelled before returning a value, it will no longer be able to finish with a value, even if the computation succeeds.
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.
Ok, that's a bit surprising to me. I guess it's because it could have children that haven't completed yet?
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, even without any children: https://pl.kotl.in/-ZYf_PR9z
The reason can be seen in the diagram in https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/ : once a Job
gets cancelled, there is no way back to being Active
or Completing
or returning a value.
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.
Makes sense, good to know 👍
* } finally { | ||
* // if `await` fails because the current job is cancelled, | ||
* // also cancel the now-unnecessary computations | ||
* deferred.cancel() |
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.
Should it be pointed out that just calling cancel
on deferred
won't prevent the current coroutine from completing before the now cancelled coroutine in the other scope completes?
Co-authored-by: Luca Kellermann <[email protected]>
With these changes, Another construct could be thought out, or an overload taking the |
@LouisCAD, what is the compilation error? I've just checked, and |
This is a small step towards deprecating the practice of breaking
structured concurrency by passing a
Job
to a coroutine builder.Thanks to @LouisCAD for the idea!
See #3670