WaitForIt

Hex.pmDocumentation

Various ways of waiting for things to happen.

WaitForIt lets you wait on the results of asynchronous or remote operations using intuitive, familiar syntax built on Elixir's own control-flow constructs (if, case, cond). It is equally at home coordinating concurrent processes in production code and taming flaky timing in tests.

# Wait until a record shows up, and bind it directly:
{:ok, user} = WaitForIt.match_wait({:ok, %User{}}, Repo.fetch(User, id), timeout: 2_000)
# Wait until an expression is truthy:
if WaitForIt.wait(File.exists?("data.csv"), timeout: :timer.minutes(1)) do
IO.puts(File.read!("data.csv"))
end

Why WaitForIt?

Elixir gives you Process.sleep/1, receive/after, and Task.await/2, but reaching for them every time you need to wait for a condition is tedious and error-prone. WaitForIt wraps that machinery in a handful of expressive macros so that "wait until X" reads like the code you'd already write — no hand-rolled polling loops, no sprinkled Process.sleep/1 calls in tests.

The five forms of waiting

FormWaits until…Looks like
wait/2an expression is truthya bare expression
match_wait/3an expression matches a pattern (binding out of it)a <- clause
case_wait/3an expression matches one of several clausesa case expression
cond_wait/2one of several expressions is truthya cond expression
with_wait/3several composed waits all succeeda with expression

Each form has a ! variant (wait!/2, match_wait!/3, …) that raises WaitForIt.TimeoutError on timeout instead of returning a falsy value or raising the matching built-in error.

Options

All forms accept the same options:

OptionDefaultDescription
:timeout5_000total time to wait, in milliseconds, before giving up
:interval100polling interval, in milliseconds, between re-evaluations (alias: :frequency)
:pre_wait0delay before the first evaluation, in milliseconds
:signaldisable polling and re-evaluate only when the named signal is received

See Polling vs signaling for when to reach for :signal.

Installation

Add wait_for_it to your dependencies in mix.exs:

def deps do
[
{:wait_for_it, "~> 2.2"}
]
end

Then require WaitForIt (or import WaitForIt) where you want to use it.

Guides

Start here and read in order, or jump to whatever fits the task at hand:

  1. Waiting in tests — the most common entry point: ExUnit assertions and using the waiting macros in tests.
  2. Polling vs signaling — the two waiting modes and when to use each.
  3. Composing waits — chaining several waits with with_wait/3.
  4. Recipes — ready-made patterns for databases, processes, HTTP, and more.
  5. Telemetry — observing waits in production.

Full API documentation is on HexDocs.

License

Apache License 2.0. See LICENSE.