I feel like I'm close here.
Let's say I have a method with a suspendCancellableCoroutine: (Sorry for any syntactical/etc. errors, just trying to get an idea down)
suspend fun foo(): String {
suspendCancellableCoroutine {
val listener = object : Listener {
override fun theThingHappened() {
it.resume("The result")
}
}
// Long involved process
thirdPartyThing.doSomethingWithListener(listener)
}
}
I call that method once, it does its thing and returns a string. But if another process calls the same method while the first CancellableContinuation is still running, is there a way to just join it and return the same result?
The reason I'm asking is that buried in my suspendCancellableCoroutine, there's a third-party method that can only run once at any given time, and attempting to run it again before the first one has completed will throw an error.
So let's say that foo() takes 10 seconds to run. It gets called once and will return the result string. But suppose that 5 seconds later another process calls it. Instead of spawning off another suspendCancellableCoroutine, can I just have the 2nd call wait for the first to finish and return that value as well?
I hope I've described this well.
Suppose you leave
foo()alone as you have defined it and create a new public functionbar()to do what you requested. I think you could do it something like this by storing a coroutine Deferred in a property. Thescopehere is a CoroutineScope appropriate for the current class. Maybe the current class creates and manages its own scope, or an outer class passes an appropriate scope to its constructor.Another possible strategy using a SharedFlow with
shareInsuch that it restarts the flow whenever it has run out of subscribers and gets a new one:Note: I didn’t test either concept.