Current section
Files
Jump to
Current section
Files
lib/asm/extensions/routing.ex
defmodule ASM.Extensions.Routing do
@moduledoc """
Public routing extension API.
This domain provides deterministic provider selection with
health-aware failover, fully owned by extension processes.
"""
use Boundary,
deps: [ASM],
exports: [
HealthTracker,
Router,
Strategy,
Strategy.Priority,
Strategy.RoundRobin,
Strategy.Weighted
]
alias ASM.Extensions.Routing.Router
@spec start_router(keyword()) :: GenServer.on_start()
def start_router(opts) when is_list(opts), do: Router.start_link(opts)
@spec select_provider(pid(), keyword()) ::
{:ok, Router.selection()} | {:error, ASM.Error.t()}
def select_provider(router, opts \\ []) when is_list(opts),
do: Router.select_provider(router, opts)
@spec report_success(pid(), Router.selection() | Router.provider_id()) ::
:ok | {:error, ASM.Error.t()}
def report_success(router, provider_ref), do: Router.report_success(router, provider_ref)
@spec report_failure(pid(), Router.selection() | Router.provider_id(), term()) ::
:ok | {:error, ASM.Error.t()}
def report_failure(router, provider_ref, reason),
do: Router.report_failure(router, provider_ref, reason)
@spec report_result(pid(), Router.selection() | Router.provider_id(), term()) ::
:ok | {:error, ASM.Error.t()}
def report_result(router, provider_ref, result) do
case result do
:ok ->
report_success(router, provider_ref)
{:ok, _value} ->
report_success(router, provider_ref)
{:error, reason} ->
report_failure(router, provider_ref, reason)
other ->
report_failure(router, provider_ref, {:unexpected_result, other})
end
end
@spec provider_health(pid(), Router.provider_id()) ::
{:ok, Router.health_status()} | {:error, ASM.Error.t()}
def provider_health(router, provider_id), do: Router.provider_health(router, provider_id)
@spec health_snapshot(pid()) :: {:ok, %{Router.provider_id() => Router.health_status()}}
def health_snapshot(router), do: Router.health_snapshot(router)
end