Grégory Lureau
02/15/2022, 3:38 PMNicklas Jensen
02/15/2022, 3:47 PMFlow<T>
where I work, titled Using Kotlin Flow in Swift, but the same idea can trivially be modified (and so have we) to support suspend
functions.
Additionally, there’s rickclephas/KMP-NativeCoroutines, which uses a Kotlin Compiler Plugin to generate these Native
wrappers, and includes a library to trivially consume them in Swift, regardless of if you’re using async/await
, Combine or RxSwift.Tim Oltjenbruns
02/15/2022, 4:00 PMTim Oltjenbruns
02/15/2022, 4:00 PMGrégory Lureau
02/15/2022, 4:44 PMsuspend
method as I'm not sure how to export Channel/Flow to JS yet, also I'm trying to provide a nice XCFramework without adding ObjectiveC code myself, and this may be the bad approach for this problem. My team exclusively consumes ObjectiveC so not sure if I could do that as nicely as you do on Swift. I'm evaluating KMP-NativeCoroutines, but looks a bit overkill to just handle cancellation on suspend method (at least, I was not expecting to add such a nice tool for this basic need).Grégory Lureau
02/15/2022, 4:50 PMCancelations are technically an error - so I would expect that to come though on the error side of the completion@Tim Oltjenbruns My problem is to cancel JS or ObjC code from Kotlin. So I need to provide them something that informs the non-coroutines code when it should cancel its work. I don't think Error/Exception can help in this case. Also CancellationException is quite unique for coroutine scope as it can have an impact on other jobs and it's currently not in Typescript signatures. I can add it myself but it means that in Kotlin code I'll have to try/catch all calls, searching for my own TS CancellationException, and map that back to Coroutines ones. That's just error-prone and easy to forget for what I consider basic coroutine contract, am I wrong?
Tim Oltjenbruns
02/15/2022, 6:05 PMTim Oltjenbruns
02/15/2022, 6:08 PMTim Oltjenbruns
02/15/2022, 6:09 PMGrégory Lureau
02/15/2022, 7:30 PMThe promise standard does not have a cancel option, and ObjC completions typically only have success/error.
What would your ideal cancelation look like from the ObjC or JS side?It could look like Kotlin actually. The big difference is that inside a suspend function in Kotlin, I can get coroutineContext.ensureActive() or isActive.
suspend fun foo() = repeat(10000) { i ->
longWorkAtIndex(i)
coroutineContext.ensureActive()
}
In this Kotlin code, the ensureActive will stop the repeat by throwing a CancellationException.
Since KMP only generates completionHandler, I need to pass myself an object that will allow me to change the isActive boolean on this object or throw an exception to define a similar code in objC/typescript (given the objC/typescript use this object to ensure cooperative cancellation).
Also, I’m not sure I understand whether you need a coroutine to tell JS/ObjC to cancel? Or do you need JS/ObjC to tell a coroutine to cancel?To be honest, I'll need both. Right now it looks like cancelling a Promise written on Typescript from Kotlin code requires this additional object. I feel like the opposite direction will be very similar (passing an object that will provide a cancel() method). How do you deal with cooperative cancellation of typescript code?