Waiting for the first coroutine to finish

We have something where we have a URI and some resolvers. We pass the URI to each resolver in turn. Each resolver handles one particular type of URI, so only one of them will return a result. So we just loop over the resolvers and break when one of them gives us a result.

But I was thinking about what might happen if we have hundreds or thousands of resolvers and we want to parallelize it. So we want to start a lot of coroutines and when one of them gives a result we cancel the others and return. Unfortunately coroutines doesn’t have an awaitFirst(), so how would I do this?

My first thought is to create a CoroutineScope, and then within that create a SharedFlow and launch all of my coroutines to run the resolvers. Each coroutine would take the SharedFlow, and if the resolver returned a value it would emit it to the flow. The flow’s collector would output the value and then cancel the scope.

Does anybody have a better idea?

How do resolvers check if they handle a specific URI? Do they check things like schema:// or other parts of the URI? If this is the case then I’m not sure it makes sense to cancel resolvers. At the time the correct resolver get the result (I/O?), all other resolvers most probably finished long ago. Also, in that case I doubt it makes sense to parallelize anything. Running some kind of a pattern matching for URI is very fast and you can easily run it for thousands of resolvers sequentially.

Anyway, you are looking for the select function.

1 Like

This would be on mobile, where the number of resolvers could be much larger than the number of cores, so many of the resolvers might not have been scheduled yet, so cancelling them would be good.

Anyway this was more theoretical for my own sake, we wouldn’t actually try to parallelize without profiling first.

And thanks, I forgot about select.