aaronrussell
aaronrussell

Reputation: 9467

Elixir waiting until any of multiple concurrent tasks completes

I have a function that posts some data over http to a host and returns an :ok or :error tuple response. I want to create some code that calls the function multiple times concurrently, posting the same data to different hosts distributed around the world, but then with the following behaviour:

For example I can send multiple requests concurrently using Task.async:

pids = [host1, host2, host3]
|> Enum.map(& Task.async(MyModule, :post_data, [&1, payload]))

I can wait for all tasks to finish using Task.yield_many, but what I can't wrap my head around is how to wait for just any of the tasks to be successful. I kind of need a Task.yield_any. Any ideas how to approach this?

Upvotes: 0

Views: 622

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

The easiest way would be probably to start tasks linked and trap exists. Once any task finishes, your code would receive :DOWN message.

The other way round would be to make your tasks send a message back to the parent process right before exiting.

Or, as a last resort, you might run Task.yield_many/2 in a loop with a quite small timeout, although it’d be kinda counter-idiomatic.

Upvotes: 1

Related Questions