I have a function something like ```suspend fun &l...
# multiplatform
s
I have a function something like
Copy code
suspend fun <T : Any> request(target: APITarget, responseDeserializer: DeserializationStrategy<T>, response: (NetworkResult) -> Unit): Cancelable
How do I test this? Wait till the response lamda completes and cross verify the result. Putting the test inside runblocking doesn’t work.
b
When testing stuff like that I know a hacky way that works most of the time. If you use this class
Copy code
class CoroutineLock() {
    private var channel by AtomicReferenceDelegate<ConflatedBroadcastChannel<Unit>?>(null)

    private val mutex = Mutex()
    val isLocked: Boolean get() = channel != null

    suspend fun lock() {
        mutex.withLock {
            val channel = channel ?: ConflatedBroadcastChannel()
            this.channel = channel
            channel.openSubscription().receive()
        }
    }

    fun unlock() {
        channel?.offer(Unit)
        channel = null
    }
}
With the AtomicReferenceDelegate being a simple ReadWriteProperty around AtomicReference to avoid mutation crashes on native. It works like the JVM
wait()
and
notify()
functions on Object. You can use this to synchronise your code the way you need to
a
Would have thought a
CompletableDeferred<NetworkResult>
was more appropriate:
Copy code
val result = CompletableDeferred<NetworkResult>()
launch { request(target, deser) { result.complete(it) } }
result.await()
something smells about having a suspend function that takes a result-emitting callback and returns a cancellation handle though. shouldn’t it just be returning NetworkResult and registering its cancellation handle with the coroutine context?
b
I agree a CompletableDeferred would be a better option
s
Yeah, Could be a wrong approach. I’m new to kotlin and kmm. Open to learning it correct way. I understand how suspend functions can return the result directly. But I don’t understand how to “registering its cancellation handle with the coroutine context?” Would be very grateful if you could point be towards an example. Basically these are network requests and I would like to have the ability to cancel them. @araqnid
a
basically, if you call
supendCancellableCoroutine
then execution is suspended, and you’re given a continuation to hook up to the callback, or call
cancel()
on
You can also do
cont.invokeOnCancellation { }
to propagate a cancellation of the coroutine context to the Cancelable
the docs for
suspendCancellableCoroutine
are a good place to look
b
Also make sure you check for cancellation @sushma nayak, you don't do it in your example @araqnid, it might not be important for your use case but it could be for others
s
suspendCancellableCoroutine
is \m/ It seems to be working. Thank you @Benoît and @araqnid 😄 People like you in the community make newbies like me survive in the platform. Could otherwise drive us away with frustration.
🎉 1
b
Glad you figured it out. And no worries, we're all someone's noob here :)