I would like to use coroutine scopes to keep track...
# getting-started
r
I would like to use coroutine scopes to keep track of how many callers are waiting for the result of a suspend function - the goal is to modify the priority of an underlying async task depending on how many callers there are. Something like this:
Copy code
interface Repo {
  /*
   1) concurrent calls to this method will not result in duplicate requests for the same url
   2) the more callers waiting on a url, the higher priority the underlying remote request
   3) if a caller's scope is cancelled, the priority of the underlying remote request is lowered
   4) if all callers' scopes are cancelled, the remote request is cancelled
  */
  suspend fun fetch(url: String): String
}
(I realize I could accomplish this using a
SharedFlow
but I’d rather expose a suspend fun that returns a scalar value) This is what I was thinking of doing to implement this - basically using a
Deferred.invokeOnCompletion
to “catch” the caller’s scope being cancelled:
Copy code
class Repo() {
 
  // something to keep track of callers/priority
  val priorities 

  // the actual remote request - runs in its own scope
  fun getOrCreateFetchJob(String): Deferred<String> 

  suspend fun fetch(url: String): String =
    CoroutineScope(currentCoroutineContext()).async {
      priorities.increase(url)
      getOrCreateFetchJob(url).await()
  }.also { 
    it.invokeOnCompletion { 
      priorities.decrease(url)
    }
  }.await()
Does this make sense? Is there a better approach?
This looks to be somewhat of what you want; may want/need to create some extra logic to handle the “priority” of the request
What does a request having “higher priority” mean exactly in this case?
☝️ 1
e
rather than
invokeOnCompletion
, just use
Copy code
priorities.increase(url)
try {
    ...
} finally {
    priorities.decrease(url)
}
👍 1
1
s
I think your original instinct is right, a shared flow would be a great way to handle this, since it keeps track of its subscriber count and can automatically stop when there are no more subscribers. You can still expose the
fetch
function to users; just use the flow as an internal implementation detail.
👍 1
r
What does a request having “higher priority” mean exactly in this case?
well, that’s ultimately up to the data fetching implementation (my example above is misleading in that respect since
priorities
is in the repo), but the plan is to send these as http priority hints