Packages

Typed distributed messaging for Gleam on the BEAM.

Retired package: Deprecated - The project needs to be redesigned around a much smaller and clearer core.

Current section

Files

Jump to
distribute src distribute@discovery@behaviour.erl
Raw

src/distribute@discovery@behaviour.erl

-module(distribute@discovery@behaviour).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/distribute/discovery/behaviour.gleam").
-export([is_transient_error/1, is_permanent_error/1, default_options/1, new_subscription_id/1, subscription_id_value/1]).
-export_type([peer_info/0, discovery_event/0, health_status/0, health_info/0, discovery_error/0, discovery_options/0, subscription_id/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Discovery behaviour contract for peer discovery.\n"
"\n"
" This module defines the contract that discovery adapters must implement\n"
" to provide peer discovery and membership tracking in the distribute library.\n"
" Discovery adapters are responsible for finding peers, tracking membership\n"
" state, and emitting membership events.\n"
"\n"
" ## Design Philosophy\n"
"\n"
" This behaviour follows distribute's patterns:\n"
" - Pure function signatures (like `crypto/provider`)\n"
" - Actor-based implementations (like `registry/actor`) \n"
" - Event-driven with `process.Subject` (like `global`, `messaging`)\n"
" - Capability negotiation support (like `handshake`)\n"
"\n"
" ## Implementation Approaches\n"
"\n"
" Adapters can be implemented as:\n"
" 1. **Actor-based**: Use `gleam/otp/actor` (recommended, see `registry/actor`)\n"
" 2. **DNS-SRV**: Query DNS for service records\n"
" 3. **Kubernetes**: Use K8s API for pod discovery\n"
" 4. **Static**: Fixed list of peers for simple deployments\n"
"\n"
" ## Integration with distribute\n"
"\n"
" Discovery adapters integrate with:\n"
" - `handshake` module for triggering negotiation when peers join\n"
" - `registry` for tracking peer metadata\n"
" - `transport` for establishing connections to discovered peers\n"
"\n"
" ## Example Implementation\n"
"\n"
" See `distribute/discovery/beam_adapter` for a reference implementation.\n"
).
-type peer_info() :: {peer_info, binary(), gleam@dict:dict(binary(), binary())}.
-type discovery_event() :: {peer_up,
binary(),
gleam@dict:dict(binary(), binary())} |
{peer_update, binary(), gleam@dict:dict(binary(), binary())} |
{peer_down, binary(), binary()}.
-type health_status() :: up | {degraded, binary()} | {down, binary()}.
-type health_info() :: {health_info,
health_status(),
gleam@option:option(integer()),
gleam@option:option(binary()),
integer()}.
-type discovery_error() :: {start_failed, binary()} |
{stop_failed, binary()} |
{shutdown_timeout, integer()} |
{sync_failed, binary()} |
{peer_not_found, binary()} |
{invalid_configuration, binary()} |
{timeout, integer()} |
{subscription_failed, binary()}.
-type discovery_options() :: {discovery_options,
binary(),
integer(),
integer(),
binary(),
list(binary()),
gleam@dict:dict(binary(), gleam@dynamic:dynamic_())}.
-opaque subscription_id() :: {subscription_id, binary()}.
-file("src/distribute/discovery/behaviour.gleam", 154).
?DOC(" Check if an error is transient and should be retried.\n").
-spec is_transient_error(discovery_error()) -> boolean().
is_transient_error(Error) ->
case Error of
{sync_failed, _} ->
true;
{timeout, _} ->
true;
_ ->
false
end.
-file("src/distribute/discovery/behaviour.gleam", 163).
?DOC(" Check if an error is permanent and should not be retried.\n").
-spec is_permanent_error(discovery_error()) -> boolean().
is_permanent_error(Error) ->
case Error of
{invalid_configuration, _} ->
true;
{peer_not_found, _} ->
true;
{start_failed, _} ->
true;
_ ->
false
end.
-file("src/distribute/discovery/behaviour.gleam", 195).
?DOC(" Create default discovery options.\n").
-spec default_options(binary()) -> discovery_options().
default_options(Name) ->
{discovery_options, Name, 5000, 10000, <<"discovery"/utf8>>, [], maps:new()}.
-file("src/distribute/discovery/behaviour.gleam", 218).
?DOC(" Create a new subscription ID.\n").
-spec new_subscription_id(binary()) -> subscription_id().
new_subscription_id(Id) ->
{subscription_id, Id}.
-file("src/distribute/discovery/behaviour.gleam", 223).
?DOC(" Extract the string value from a subscription ID.\n").
-spec subscription_id_value(subscription_id()) -> binary().
subscription_id_value(Id) ->
{subscription_id, Value} = Id,
Value.