Reputation: 236
I have a parallel map in Elixir using Task.async
. I am using it with System.cmd
to parallel ruby rbenv install
a list of ruby version strings.
The script runs and installs the ruby versions. However it does not exit the Task
once the ruby versions have been installed and errors with a Task.await timeout error.
I have tried passing a simple IO.puts function into the parallel map and behaves correctly, exiting when the work is done and not raising an error. What am I missing in my System.cmd
to ensure that each process is ended once each rbenv process is finished.
# My parallel map
def pmap(collection, func) do
collection
|> Enum.map(&(Task.async(fn -> func.(&1) end)))
|> Enum.map(&Task.await/1)
end
# System.cmd is being passed into the map like this
def parallel_install(ruby_versions) do
pmap(ruby_versions, &(System.cmd("rbenv", ["install", &1])))
end
Output with Error:
rbenv: /Users/lewis.jones/.rbenv/versions/2.4.4 already exists
rbenv: /Users/lewis.jones/.rbenv/versions/2.5.1 already exists
rbenv: /Users/lewis.jones/.rbenv/versions/2.1.10 already exists
rbenv: /Users/lewis.jones/.rbenv/versions/2.3.7 already exists
rbenv: /Users/lewis.jones/.rbenv/versions/2.2.10 already exists
** (exit) exited in: Task.await(%Task{owner: #PID<0.73.0>, pid: #PID<0.82.0>,
ref: #Reference<0.100168651.1374158856.61975>}, 5000)
** (EXIT) time out
(elixir) lib/task.ex:491: Task.await/2
(elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/code.ex:376: Code.require_file/2
Upvotes: 0
Views: 469
Reputation: 222188
Task.await
defaults to a timeout of 5 seconds. I'm guessing rbenv install
takes longer than that. You can either increase the timeout or set it to infinity.
300 seconds:
|> Enum.map(&Task.await(&1, 300_000))
or infinity:
|> Enum.map(&Task.await(&1, :infinity))
Upvotes: 1