Packages

A Reactor extension which provides steps for working with supervisors.

Current section

Files

Jump to
reactor_process lib reactor process utils.ex
Raw

lib/reactor/process/utils.ex

# SPDX-FileCopyrightText: 2025 reactor_process contributors <https://github.com/ash-project/reactor_process/graphs/contributors>
#
# SPDX-License-Identifier: MIT
defmodule Reactor.Process.Utils do
@moduledoc false
alias Reactor.Process.Errors.TerminateTimeoutError
@doc "Terminate a process while waiting for it to exit"
@spec terminate(pid, any, timeout, Reactor.Step.t()) ::
:ok | {:error, TerminateTimeoutError.t()}
def terminate(pid, reason, timeout, step) when is_pid(pid) do
ref = Process.monitor(pid)
Process.unlink(pid)
Process.exit(pid, reason)
await_exit(pid, ref, timeout, step)
end
@doc "Await a process termination"
@spec await_exit(pid, reference, timeout, Reactor.Step.t()) ::
:ok | {:error, TerminateTimeoutError.t()}
def await_exit(pid, ref, timeout, step) do
receive do
{:DOWN, ^ref, :process, ^pid, _} ->
Process.demonitor(ref, [:flush])
:ok
after
timeout ->
Process.demonitor(ref, [:flush])
{:error,
TerminateTimeoutError.exception(
step: step,
timeout: timeout,
process: pid
)}
end
end
@doc "Convert a module spec into a child spec"
@spec child_spec(Supervisor.module_spec()) :: {:ok, Supervisor.child_spec()} | {:error, any}
def child_spec({module, opts}) do
{:ok, module.child_spec(opts)}
rescue
error -> {:error, error}
end
def child_spec(module) do
{:ok, module.child_spec([])}
rescue
error -> {:error, error}
end
end