https://kotlinlang.org logo
a

Alexander Vtyurin

06/26/2019, 7:27 PM
Proposal: make
suspendCancelableCoroutine
a part of the language instead of
suspendCoroutine
as a more general and tweakable language unit.
1
⏸️ 2
e

elizarov

06/26/2019, 8:15 PM
Unfortunately, adding
suspendCancellableCoroutine
would mean adding
Job
and all it cancellation machinery which contains quite a lot of code. That is too much for our vision of Kotlin standard library. Moreover, while the contract are quite stable since
kotlinx.coroutines
version
1.0
we are still evolving implementation details considerably.
a

Alexander Vtyurin

06/26/2019, 9:01 PM
=C Is there a way to provide minimum cancelable logic into
suspendCoroutine
keeping a way to integrate with it from
kotlinx.coroutines
simple? Like, I have a small pet project and I don't want to pull whole coroutines with me, I only want an ability to cancel it.
1
l

louiscad

06/26/2019, 9:16 PM
Why don't you want to "pull whole kotlinx.coroutines" in that project exactly?
s

simon.vergauwen

06/26/2019, 10:23 PM
I've had the same paint point.
Why don't you want to "pull whole kotlinx.coroutines" in that project exactly?
AFAIK the reason for separation std and kotlinx was so that you didn't have to rely on kotlinx and can simple rely on std.
Is there any technical reason why
suspendCancelableContinuation
(and
startCancelableContinuation
?) can't be separated from
Job
or other kotlinx implementation details? Or could it be separated by other abstractions?
g

gildor

06/27/2019, 2:41 AM
But you need some abstraction (some CoroutineContext) for cancellation which is what Job is
I would prefer to extract suspendCancelableContinuation and Job to some kotlinx.coroutines.cancellation artifact, which will be even more core part of kotlinx.coroutines, so it would be possible to use it for third-party implementations without dependency on higher-level primitives (personally I would also prefer to separate Flow and Channels from core)
Would be also interesting to have the same for dispatchers
r

raulraja

06/27/2019, 3:39 AM
Would that impose cooperative cancelation over libraries?. Imo built in cancellation is fine but if it's abstract enough for library authors to add their own semantics.
g

gildor

06/27/2019, 3:50 AM
Job is just an interface, so it should be possible to provide own behavior with own Job implementation, it just should follow Job state contract
e

elizarov

06/27/2019, 7:07 AM
Job is a use-only interface, It has non-trivial state-machine and exception handling logic to make sure they are never lost. We have not yet found a way how to abstract it to make 3rd party implementations of this interface possible and safe at the same time.
Unfortunately, dispatchers are also integrated with cancellation both for functionality (make sure cancelled coroutines do not run normally) and for some performance optimizations (avoiding extra wrapper objects allocations).
Anyway, simplifying Job and making it possible to be alternatively implemented is an extremely desirable thing. I’d love to do it, just have not figured out how.
🙏 1
g

gildor

06/27/2019, 7:32 AM
I think it’s fine to have separate Dispatchers artifact with cancellation in dependencies
s

simon.vergauwen

06/27/2019, 7:33 AM
Those all sound like kotlinx impl details. Generic cancelation is just about a handler and cancelable reference, no? Which is what we'd care to abstract from Job.
a

Alexander Vtyurin

06/27/2019, 10:51 AM
Yes, maybe it will make
std
weight a couple of kilos more, but anyway, I think that it is more correct for
suspendCancelableCoroutine
to be a part of a language because without it no one can implement their own
com.username.kotlin-coroutines
that will be compatible with
kotlinx
at least in some way. Especially in a case when
Job
impl is complex and should not be touched without knowledge.
1
1
g

gildor

06/27/2019, 10:54 AM
It’s not a problem of “a couple of kilos”
What is added to stdlib once cannot be removed/changed in a backward incompatible way never in Kotlin 1.x
Why add something to language if it may be extracted to library with much faster release schedule and softer backward compatibility rules
3
a

Alexander Vtyurin

06/27/2019, 10:58 AM
Unfortunately, adding
suspendCancellableCoroutine
would mean adding
Job
and all it cancellation machinery which contains quite a lot of code.
So, you're saying that JB team is not sure for current
Job
impl and there are risks in this decision if sometime later you'll decide to reimplement it?
g

gildor

06/27/2019, 11:01 AM
Sure, why not?
s

simon.vergauwen

06/27/2019, 11:01 AM
suspendCancelableContinuation
should be decoupled from
Job
.
g

gildor

06/27/2019, 11:01 AM
Also Job is not an implementation
suspendCancelableContinuation
should be decoupled from
Job
.
And how would it work?
You need some coroutine context that keeps coroutine state (let’s name it for example Job!)
s

simon.vergauwen

06/27/2019, 11:02 AM
Job
currently leaks kotlinx details
g

gildor

06/27/2019, 11:02 AM
Not sure exactly, but of course, it may be
so it means that we need some lower level primitive for this
which doesn’t exist yet
Move suspendCancelableContinuation to stdlib is not just copy one function
Not sure why we discussing it again, it’s exactly what Roman said above: https://kotlinlang.slack.com/archives/C0B9K7EP2/p1561619268110300?thread_ts=1561577221.102900&cid=C0B9K7EP2
s

simon.vergauwen

06/27/2019, 11:06 AM
It should just be a plain cancelation contract. However it's modeled best for Kotlin.
g

gildor

06/27/2019, 11:07 AM
which doesn’t exist yet
I mean we are trying to discuss moving to stdlib code that not even exist
s

simon.vergauwen

06/27/2019, 11:07 AM
Exactly
g

gildor

06/27/2019, 11:08 AM
And before move it to stdlib it should be at least tested on kotlinx.coroutines
and to do this it should be extracted to own library to test how it works with 3rd party implementations
and if it extracted, what is the point to bundle it to stdlib if it not even used there?
s

simon.vergauwen

06/27/2019, 11:09 AM
You can write cancelable coroutine code by just using the std?
Continuation can be run in many different ways. Not just kotlinx.
g

gildor

06/27/2019, 11:09 AM
No, you cannot, you cannot even run it using stdlib
s

simon.vergauwen

06/27/2019, 11:09 AM
You can
The new IO in Arrow does exactly that
g

gildor

06/27/2019, 11:10 AM
But you have own dispatchers, as I understand, isn’t it?
s

simon.vergauwen

06/27/2019, 11:10 AM
No
g

gildor

06/27/2019, 11:10 AM
What do you use to run it?
s

simon.vergauwen

06/27/2019, 11:11 AM
startCoroutine
With
suspendCancelableContinuation
we could integrate IOs cancelation in an interopt way
If that was not the original goal of this proposal than I miss understood :)
g

gildor

06/27/2019, 11:26 AM
But because suspendCancelableContinuation is not enough…
we returning back to Job
s

simon.vergauwen

06/27/2019, 11:27 AM
Why is
suspendCancelableContinuation
not enough?
You'd also need
startCoroutineCancelable
if that's what you mean.
g

gildor

06/27/2019, 11:28 AM
How would it be implemented?
My point that to get some result with this feature request, better to discuss what is not enough for your implementation and propose to extract this part to separate library (and create task on kotlinx.coroutinws tracker), so it would be possible to write third party implementations without waiting for stdlib
Also even now CancellableContinuation has experimental APIs
s

simon.vergauwen

06/27/2019, 11:38 AM
I don't expect this to happen anytime soon as building or architecting cancelable effect systems is very difficult. Probably the hardest thing I've done till date myself was the work on Arrow's IO, and specifically cancelation.
I was still more wondering if it's a good fit on a language level. I do have a good use case for it, but nothing that can't be solved atm by offering an kotlinx integration module.
That doesn't change the fact that it's broken IMO. It should be sufficient to integrate with std, but all cancelation out there currently requires the need for kotlinx. I.e Android, there is not way to integrate cancelation on a language level. All libraries need to provide custom integrations which is horrible for library authors and also for users.
e

elizarov

06/27/2019, 4:38 PM
Sorry, but I don’t see how the discussion on cancellation decoupling is relevant to stdlib. I totally agree with what @gildor said. When we figure out how to decouple cancellation from the rest of
kotlinx.coroutines
it would still make total sense to keep it separately. I don’t see much benefit in adding it to the stdlib, whoever needs it can easily add a dependency.
s

simon.vergauwen

06/27/2019, 4:42 PM
May I ask why? The power of being able to define cancelable suspending function based on the std seems exactly what you'd want. If it's tied to a library that seriously weakens the power of
suspend
as a language feature as a result imo.
e

elizarov

06/27/2019, 4:43 PM
Because there is no point in just keeping adding stuff to stdlib. None. It’s year 2019. Dependencies were invented long time ago.
(we don’t want to turn into yet another Java)
s

simon.vergauwen

06/27/2019, 4:46 PM
Fair but not sure I understand why Kotlin shouldn't support cancelable suspending function as a language feature.
And/or make the existing std operators cancelable aware.
e

elizarov

06/27/2019, 4:47 PM
Because it has nothing to do with a language. Suspension support is a language feature. Cancellation is totally library feature
s

simon.vergauwen

06/27/2019, 4:47 PM
Is there any resource or technical paper on this? I'm not sure I understand why.
Is this something other language have discussed?
e

elizarov

06/27/2019, 4:48 PM
You can read the paper on design of coroutines in Kotlin: https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md
It describes the language design for suspension and does not mention cancellation, because it is not related to cancellation in any way.
Moreover, I’ve never seen a language where cancellation is supported on language level. For all I know, it is always implemented in a library.
s

simon.vergauwen

06/27/2019, 4:55 PM
Thank you for the reference! On a similar note, what would recommend for Arrow's IO? Interopt in an uncancelable manner using std tools and provide a seperate kotlinx module to integrate IOs cancelation with `CoroutineScope`/structured concurrency? I.e for easy interopt with Kotlinx on Android?
l

louiscad

06/27/2019, 5:22 PM
@simon.vergauwen I'd recommend to use non experimental APIs of kotlinx.coroutines, simply. If size is a concern, some people will be writing assembly, others will use R8, Proguard, DCE or other binary optimizers.
👍 1
s

simon.vergauwen

06/27/2019, 5:35 PM
@louiscad we don't rely on Kotlinx in Arrow Fx. It'll be a seperate artifact to integrate with Kotlinx , so all integrations that makes sense will be included. Edit: we don't rely on Kotlinx coroutines, we rely on some others and might more in the future with libs like atomicfu and clock.
4 Views