I notice `suspend` functions get translated to `as...
# multiplatform
u
I notice
suspend
functions get translated to
async throws
automatically, which is neet This however doesn't support cancellation, i.e. when swift
Task
gets cancelled, the source kotlin coroutine keeps on going (In my local testing) So, why is this. Is
async
function some sort of sideffect of objc, rather than a deliberate kotlin native decision? Can I somehow influence the
suspend -> async
adapter?
e
https://youtrack.jetbrains.com/issue/KT-47042
Cancellation, dispatchers, coroutine context, task locals etc. are not propagated between Kotlin and Swift, they are discarded at the boundary between Kotlin and Swift.
I think this is inevitable for now, because this is building on the Swift's automatic Objective-C completion handler to async translation
u
so it just a sugar for the completion handler api?
u
okay so this necessarily doesn't have anything to do with kmm/kn
e
this could be addressed if K/N generated Swift bindings instead of Objective-C. but that's still a ways off. https://youtrack.jetbrains.com/issue/KT-49131
u
hm, how would that even work? I'd need a CoroutineScope to launch the suspend fun in exposed to Swift, no?
e
I haven't seen any designs around it
but Swift has its own (optional) structured concurrency that could be used, perhaps by wrapping with https://developer.apple.com/documentation/swift/withunsafecurrenttask(body:)
u
okay so to have cancellation, the only way is to have some wrapper in kotlin which will own the coroutine scope, launch the function in that scope, and provide callback api + cancellation handle, to swift
where I'd wrap to async/await with their coroutine builder thingy
e
or some wrapper in Swift that turns its Task/TaskGroup into a Kotlin CoroutineScope, and then executes the Kotlin suspend fun with it
it'll probably have to be optional though, since there's uses of
suspend fun
that aren't kotlinx.coroutines
u
I don't follow..how? is that possible with the current library?
I thought all notions of
suspend
were stripped at the boundary
e
in principle it's possible. none of the code to do it exists afaik
h
is this for trying to call a suspend function in shared folder from a aync function in Swift?
Because I am also having this problem
e
no, you have a different problem
u
I see, so possibly in future
wondering about some generic thing, but that would require a suspending lambda, .. so only concrete wrappers .. i.e. codegen to the rescue?
but the adapter will live in kotlin, so its fine .. lmao the rubberducking, sorry 😄
Copy code
class SuspendAdapter<T> {
	private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())

	fun adapt(action: suspend () -> R, onNext: () -> R) : CancellationHandle {
		val job = scope.launch {
			val result = action()
			onNext(result)
		}
		return CancellationHandle(job)
	}
}
nevermind you'd need a concrete FooAdapter class anyways to wrap Foo api .. so yea, codegen to generate them
thanks!
e
hmm, seems my previous proposal sorta exists in some form (although it uses one common scope instead of creating one per swift operation as I'd have chosen). https://github.com/rickclephas/KMP-NativeCoroutines/blob/master/KMPNativeCoroutinesAsync/AsyncFunction.swift
207 Views