Skip to content

Commit

Permalink
Add Process.sleep/1
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Jan 30, 2016
1 parent 9db8a70 commit ef2839d
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
74 changes: 74 additions & 0 deletions lib/elixir/lib/process.ex
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -121,6 +121,80 @@ defmodule Process do
:erlang.exit(pid, reason) :erlang.exit(pid, reason)
end end


@doc """
Sleeps the current process by `timeout`.
`timeout` is either the number of miliseconds to sleep as an
integer or the atom `:infinity`. When `:infinity` is given,
the current process will suspend forever.
**Use this function with extreme care**. For almost all situations
where you would use `sleep/1` in Elixir, there is likely a
more correct, faster and precise way of achieving it with
message passing.
For example, if you are waiting a process to perform some
action, it is better to communicate.
In other words, **do not**:
Task.start_link fn ->
do_something()
...
end
# Wait until work is done
Process.sleep(2000)
But **do**:
parent = self()
Task.start_link fn ->
do_something()
send parent, :work_is_done
...
end
receive do
:work_is_done -> :ok
after
30_000 -> :timeout # Optional timeout
end
Or even use `Task.async/1` and `Task.await/2` in the example
above.
Similarly, if you are waiting for a process to terminate,
use monitor instead of sleep. **Do not**:
Task.start_link fn ->
...
end
# Wait until task terminates
Process.sleep(2000)
Instead **do**:
{:ok, pid} =
Task.start_link fn ->
...
end
ref = Process.monitor(pid)
receive do
{:DOWN, ^ref, _, _, _} -> :task_is_down
after
30_000 -> :timeout # Optional timeout
end
"""
def sleep(timeout)
when is_integer(timeout) and timeout >= 0
when timeout == :infinity do
receive after: (timeout -> :ok)
end

@doc """ @doc """
Sends a message to the given process. Sends a message to the given process.
Expand Down
4 changes: 4 additions & 0 deletions lib/elixir/test/elixir/process_test.exs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ defmodule ProcessTest do
quote(do: :erlang.monitor(:process, pid())) quote(do: :erlang.monitor(:process, pid()))
end end


test "sleep/1" do
assert Process.sleep(0) == :ok
end

test "info/2" do test "info/2" do
pid = spawn fn -> :timer.sleep(1000) end pid = spawn fn -> :timer.sleep(1000) end
assert Process.info(pid, :priority) == {:priority, :normal} assert Process.info(pid, :priority) == {:priority, :normal}
Expand Down

1 comment on commit ef2839d

@avocade
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect.

Please sign in to comment.