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
Current section
Files
src/distribute@registry.erl
-module(distribute@registry).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/distribute/registry.gleam").
-export([register/2, unregister/1, whereis/1]).
-export_type([register_error/0, dynamic_/0, pid_/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.
-type register_error() :: already_registered |
invalid_process |
{invalid_name, binary()} |
{network_error, binary()} |
{register_failed, binary()}.
-type dynamic_() :: any().
-type pid_() :: any().
-file("src/distribute/registry.gleam", 69).
?DOC(" Convert RegisterError to string for logging\n").
-spec classify_register_error_to_string(register_error()) -> binary().
classify_register_error_to_string(Error) ->
case Error of
already_registered ->
<<"already_registered"/utf8>>;
invalid_process ->
<<"invalid_process"/utf8>>;
{invalid_name, Msg} ->
<<"invalid_name: "/utf8, Msg/binary>>;
{network_error, Msg@1} ->
<<"network_error: "/utf8, Msg@1/binary>>;
{register_failed, Msg@2} ->
<<"register_failed: "/utf8, Msg@2/binary>>
end.
-file("src/distribute/registry.gleam", 80).
?DOC(" Check if error is network-related\n").
-spec is_network_error(binary()) -> boolean().
is_network_error(Reason) ->
(gleam_stdlib:contains_string(Reason, <<"partition"/utf8>>) orelse gleam_stdlib:contains_string(
Reason,
<<"network"/utf8>>
))
orelse gleam_stdlib:contains_string(Reason, <<"connection"/utf8>>).
-file("src/distribute/registry.gleam", 55).
?DOC(" Classify error reason into structured RegisterError\n").
-spec classify_register_error(binary()) -> register_error().
classify_register_error(Reason) ->
case Reason of
<<"already_registered"/utf8>> ->
already_registered;
<<"invalid_process"/utf8>> ->
invalid_process;
<<"invalid_name"/utf8>> ->
{invalid_name, <<"Name contains invalid characters"/utf8>>};
_ ->
case is_network_error(Reason) of
true ->
{network_error, Reason};
false ->
{register_failed, Reason}
end
end.
-file("src/distribute/registry.gleam", 87).
?DOC(" Validate registry name\n").
-spec validate_name(binary()) -> {ok, nil} | {error, register_error()}.
validate_name(Name) ->
case string:length(Name) of
0 ->
{error, {invalid_name, <<"Name cannot be empty"/utf8>>}};
Len when Len > 255 ->
{error, {invalid_name, <<"Name too long (max 255 chars)"/utf8>>}};
_ ->
case gleam_stdlib:contains_string(Name, <<" "/utf8>>) of
true ->
{error,
{invalid_name, <<"Name cannot contain spaces"/utf8>>}};
false ->
{ok, nil}
end
end.
-file("src/distribute/registry.gleam", 100).
?DOC(" Register a process globally under the given name.\n").
-spec register(binary(), pid_()) -> {ok, nil} | {error, register_error()}.
register(Name, Pid) ->
distribute@log:debug(
<<"Registering global name"/utf8>>,
[{<<"name"/utf8>>, Name}]
),
case validate_name(Name) of
{error, E} ->
distribute@log:warn(
<<"Name validation failed during registration"/utf8>>,
[{<<"name"/utf8>>, Name},
{<<"error"/utf8>>, classify_register_error_to_string(E)}]
),
{error, E};
{ok, _} ->
Res = registry_ffi:register(Name, Pid),
case registry_ffi:is_ok_atom(Res) of
true ->
distribute@log:info(
<<"Successfully registered global name"/utf8>>,
[{<<"name"/utf8>>, Name}]
),
{ok, nil};
false ->
case registry_ffi:is_already_registered(Res) of
true ->
distribute@log:warn(
<<"Name already registered"/utf8>>,
[{<<"name"/utf8>>, Name}]
),
{error, already_registered};
false ->
Error = classify_register_error(
registry_ffi:get_error_reason(Res)
),
distribute@log:error(
<<"Failed to register global name"/utf8>>,
[{<<"name"/utf8>>, Name},
{<<"error"/utf8>>,
classify_register_error_to_string(Error)}]
),
{error, Error}
end
end
end.
-file("src/distribute/registry.gleam", 138).
?DOC(" Unregister a globally registered name.\n").
-spec unregister(binary()) -> {ok, nil} | {error, register_error()}.
unregister(Name) ->
Res = registry_ffi:unregister(Name),
case registry_ffi:is_ok_atom(Res) of
true ->
{ok, nil};
false ->
{error, classify_register_error(registry_ffi:get_error_reason(Res))}
end.
-file("src/distribute/registry.gleam", 148).
?DOC(
" Look up a globally registered process by name.\n"
" Returns Some(pid) if found, None otherwise.\n"
).
-spec whereis(binary()) -> gleam@option:option(pid_()).
whereis(Name) ->
distribute@log:debug(
<<"Resolving global name"/utf8>>,
[{<<"name"/utf8>>, Name}]
),
Res = registry_ffi:whereis(Name),
case registry_ffi:is_pid(Res) of
true ->
{some, registry_ffi:dynamic_to_pid(Res)};
false ->
none
end.