Packages

A Reactor extension which provides steps for working with supervisors.

Current section

Files

Jump to
reactor_process lib reactor process step process_exit.ex
Raw

lib/reactor/process/step/process_exit.ex

# SPDX-FileCopyrightText: 2025 reactor_process contributors <https://github.com/ash-project/reactor_process/graphs/contributors>
#
# SPDX-License-Identifier: MIT
defmodule Reactor.Process.Step.ProcessExit do
@arg_schema Spark.Options.new!(
process: [
type: :pid,
required: true,
doc: "The process to terminate"
],
reason: [
type: :any,
required: true,
doc: "The termination reason"
],
timeout: [
type: :timeout,
required: false,
default: 5_000,
doc: "How long to wait for the process to terminate before timing out"
]
)
@opt_schema Spark.Options.new!(
wait_for_exit?: [
type: :boolean,
required: false,
default: false,
doc: "Whether to wait for the process to exit before continuing"
]
)
@moduledoc """
A Reactor step which sends an exit signal to the process.
When the `wait_for_exit?` option is `true` the step will monitor the process
until it exits or times out.
## Arguments
#{Spark.Options.docs(@arg_schema)}
## Options
#{Spark.Options.docs(@opt_schema)}
"""
use Reactor.Step
import Reactor.Process.Utils
@doc false
@impl true
def run(arguments, context, options) do
with {:ok, arguments} <- Spark.Options.validate(Enum.to_list(arguments), @arg_schema),
{:ok, options} <- Spark.Options.validate(options, @opt_schema),
{:ok, process} <- Keyword.fetch(arguments, :process),
{:ok, reason} <- Keyword.fetch(arguments, :reason) do
send_exit(process, reason, arguments[:timeout], options, context)
end
end
defp send_exit(process, reason, timeout, options, context) do
if options[:wait_for_exit?] do
case terminate(process, reason, timeout, context.current_step) do
:ok -> {:ok, reason}
{:error, reason} -> {:error, reason}
end
else
Process.exit(process, reason)
{:ok, reason}
end
end
end