Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait an Elixir spawned process to end like Ruby's Thread#join

I have a following Ruby code:

t = Thread.new do
  sleep(1)
  puts "Finished!"
end

t.join

How can I write an equivalent code in Elixir?

I wrote the following one:

spawn fn ->
  :timer.sleep(1000)
  IO.puts "Finished!"
end

:timer.sleep(1000)

It works but this is not equivalent to the Ruby version.

like image 389
Tsutomu Avatar asked Nov 29 '22 09:11

Tsutomu


2 Answers

You can use Process.monitor/1 and receive for this:

pid = spawn(fn ->
  :timer.sleep(1000)
  IO.puts "Finished!"
end)

# Start monitoring `pid`
ref = Process.monitor(pid)

# Wait until the process monitored by `ref` is down.
receive do
  {:DOWN, ^ref, _, _, _} ->
    IO.puts "Process #{inspect(pid)} is down"
end

Output:

Finished!
Process #PID<0.73.0> is dead

Process #PID<0.73.0> is dead is printed just after Finished!.

like image 129
Dogbert Avatar answered Dec 19 '22 09:12

Dogbert


Instead of aiming for something as equivalent as possible, here's what I'd consider a more idiomatic approach to the problem of "run a background process that sleeps for a second, and don't exit the script until it finishes."

Task.async(fn -> :timer.sleep(1000) end)
|> Task.await
like image 27
Martin Svalin Avatar answered Dec 19 '22 09:12

Martin Svalin