defmodule NoizuLabs.Entities.Helpers do @moduledoc """ Helper utilities for entities. """ @doc """ Wait until condition lambda returns an ok tuple or timeout exceeded. """ def wait_for_condition(condition, timeout \\ 5_000, options \\ nil) def wait_for_condition(condition, timeout, options) do reference = make_ref() task = Task.async(fn -> wait_loop(condition, reference, options) end) case Task.yield(task, timeout) do {:ok, response} -> {:ok, response} _ -> response = receive do {:condition_not_met, response} -> {:timeout, response} e -> {:timeout, e} after 50 -> {:timeout, :timeout} end Task.shutdown(task, 0) response end end defp wait_loop(condition, reference, options) do case condition.() do true -> :ok :ok -> :ok {:ok, details} -> {:ok, details} response -> send(reference, {:condition_not_met, response}) :timer.sleep(options[:poll] || 100) wait_loop(condition, reference, options) end end end