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@actor.erl
-module(distribute@registry@actor).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/distribute/registry/actor.gleam").
-export([register_sync/4, lookup_sync/3, unregister_sync/3, list_nodes_sync/2, start/0, start_link/0, child_spec/0]).
-export_type([registry_command/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 registry_command() :: {register,
binary(),
distribute@registry@behaviour:metadata(),
gleam@erlang@process:subject({ok, nil} | {error, binary()})} |
{unregister,
binary(),
gleam@erlang@process:subject({ok, nil} | {error, binary()})} |
{lookup,
binary(),
gleam@erlang@process:subject({ok,
distribute@registry@behaviour:metadata()} |
{error, nil})} |
{list_all,
gleam@erlang@process:subject({ok, list(binary())} | {error, nil})}.
-file("src/distribute/registry/actor.gleam", 105).
?DOC(" Typed synchronous helper: register node metadata via the registry actor.\n").
-spec register_sync(
gleam@erlang@process:subject(registry_command()),
integer(),
binary(),
distribute@registry@behaviour:metadata()
) -> {ok, nil} | {error, distribute@registry@behaviour:registry_error()}.
register_sync(Registry, Timeout_ms, Node_id, Metadata) ->
case string:length(Node_id) of
0 ->
{error, {invalid_argument, <<"node_id cannot be empty"/utf8>>}};
Len when Len > 255 ->
{error, {invalid_argument, <<"node_id too long"/utf8>>}};
_ ->
case Metadata of
{metadata, Md_node, _, _} ->
case Md_node =:= Node_id of
true ->
Res = gleam@erlang@process:call(
Registry,
Timeout_ms,
fun(Reply) ->
{register, Node_id, Metadata, Reply}
end
),
case Res of
{ok, nil} ->
{ok, nil};
{error, _} ->
{error,
{adapter_failure,
<<"actor failure"/utf8>>}}
end;
false ->
{error,
{invalid_argument,
<<"metadata.node_id mismatch"/utf8>>}}
end
end
end.
-file("src/distribute/registry/actor.gleam", 138).
?DOC(" Typed synchronous lookup helper.\n").
-spec lookup_sync(
gleam@erlang@process:subject(registry_command()),
integer(),
binary()
) -> {ok, distribute@registry@behaviour:metadata()} |
{error, distribute@registry@behaviour:registry_error()}.
lookup_sync(Registry, Timeout_ms, Node_id) ->
Res = gleam@erlang@process:call(
Registry,
Timeout_ms,
fun(Reply) -> {lookup, Node_id, Reply} end
),
case Res of
{ok, Md} ->
{ok, Md};
{error, _} ->
{error, not_found}
end.
-file("src/distribute/registry/actor.gleam", 152).
?DOC(" Typed synchronous unregister helper.\n").
-spec unregister_sync(
gleam@erlang@process:subject(registry_command()),
integer(),
binary()
) -> {ok, nil} | {error, distribute@registry@behaviour:registry_error()}.
unregister_sync(Registry, Timeout_ms, Node_id) ->
Res = gleam@erlang@process:call(
Registry,
Timeout_ms,
fun(Reply) -> {unregister, Node_id, Reply} end
),
case Res of
{ok, nil} ->
{ok, nil};
{error, _} ->
{error, {adapter_failure, <<"actor failure"/utf8>>}}
end.
-file("src/distribute/registry/actor.gleam", 166).
?DOC(" List known node ids synchronously.\n").
-spec list_nodes_sync(
gleam@erlang@process:subject(registry_command()),
integer()
) -> list(binary()).
list_nodes_sync(Registry, Timeout_ms) ->
Res = gleam@erlang@process:call(
Registry,
Timeout_ms,
fun(Reply) -> {list_all, Reply} end
),
case Res of
{ok, Ids} ->
Ids;
{error, _} ->
[]
end.
-file("src/distribute/registry/actor.gleam", 187).
-spec remove(
list({binary(), distribute@registry@behaviour:metadata()}),
binary()
) -> list({binary(), distribute@registry@behaviour:metadata()}).
remove(Items, Node_id) ->
gleam@list:filter(
Items,
fun(Pair) -> erlang:element(1, Pair) /= Node_id end
).
-file("src/distribute/registry/actor.gleam", 178).
-spec upsert(
list({binary(), distribute@registry@behaviour:metadata()}),
binary(),
distribute@registry@behaviour:metadata()
) -> list({binary(), distribute@registry@behaviour:metadata()}).
upsert(Items, Node_id, Metadata) ->
Without = remove(Items, Node_id),
[{Node_id, Metadata} | Without].
-file("src/distribute/registry/actor.gleam", 194).
-spec find(list({binary(), distribute@registry@behaviour:metadata()}), binary()) -> gleam@option:option(distribute@registry@behaviour:metadata()).
find(Items, Node_id) ->
Filtered = gleam@list:filter(
Items,
fun(Pair) -> erlang:element(1, Pair) =:= Node_id end
),
case gleam@list:first(Filtered) of
{ok, Pair@1} ->
case Pair@1 of
{_, Md} ->
{some, Md}
end;
{error, _} ->
none
end.
-file("src/distribute/registry/actor.gleam", 25).
?DOC(
" Start the registry actor. Returns a `Subject(RegistryCommand)` which\n"
" accepts the commands defined above.\n"
).
-spec start() -> {ok, gleam@erlang@process:subject(registry_command())} |
{error, gleam@otp@actor:start_error()}.
start() ->
_pipe = gleam@otp@actor:new([]),
_pipe@1 = gleam@otp@actor:on_message(
_pipe,
fun(State, Msg) -> case {State, Msg} of
{Items, {register, Node_id, Metadata, Reply}} ->
New_state = upsert(Items, Node_id, Metadata),
gleam@erlang@process:send(Reply, {ok, nil}),
gleam@otp@actor:continue(New_state);
{Items@1, {unregister, Node_id@1, Reply@1}} ->
New_state@1 = remove(Items@1, Node_id@1),
gleam@erlang@process:send(Reply@1, {ok, nil}),
gleam@otp@actor:continue(New_state@1);
{Items@2, {lookup, Node_id@2, Reply@2}} ->
case find(Items@2, Node_id@2) of
{some, Metadata@1} ->
gleam@erlang@process:send(Reply@2, {ok, Metadata@1});
none ->
gleam@erlang@process:send(Reply@2, {error, nil})
end,
gleam@otp@actor:continue(Items@2);
{Items@3, {list_all, Reply@3}} ->
Ids = gleam@list:map(
Items@3,
fun(Pair) -> erlang:element(1, Pair) end
),
gleam@erlang@process:send(Reply@3, {ok, Ids}),
gleam@otp@actor:continue(Items@3)
end end
),
_pipe@2 = gleam@otp@actor:start(_pipe@1),
gleam@result:map(_pipe@2, fun(Started) -> erlang:element(3, Started) end).
-file("src/distribute/registry/actor.gleam", 61).
?DOC(
" Start the registry actor returning the raw `actor.Started` result.\n"
"\n"
" Useful for OTP supervision where the supervisor expects a start\n"
" function that returns `Result(actor.Started(data), actor.StartError)`.\n"
).
-spec start_link() -> {ok,
gleam@otp@actor:started(gleam@erlang@process:subject(registry_command()))} |
{error, gleam@otp@actor:start_error()}.
start_link() ->
_pipe = gleam@otp@actor:new([]),
_pipe@1 = gleam@otp@actor:on_message(
_pipe,
fun(State, Msg) -> case {State, Msg} of
{Items, {register, Node_id, Metadata, Reply}} ->
New_state = upsert(Items, Node_id, Metadata),
gleam@erlang@process:send(Reply, {ok, nil}),
gleam@otp@actor:continue(New_state);
{Items@1, {unregister, Node_id@1, Reply@1}} ->
New_state@1 = remove(Items@1, Node_id@1),
gleam@erlang@process:send(Reply@1, {ok, nil}),
gleam@otp@actor:continue(New_state@1);
{Items@2, {lookup, Node_id@2, Reply@2}} ->
case find(Items@2, Node_id@2) of
{some, Metadata@1} ->
gleam@erlang@process:send(Reply@2, {ok, Metadata@1});
none ->
gleam@erlang@process:send(Reply@2, {error, nil})
end,
gleam@otp@actor:continue(Items@2);
{Items@3, {list_all, Reply@3}} ->
Ids = gleam@list:map(
Items@3,
fun(Pair) -> erlang:element(1, Pair) end
),
gleam@erlang@process:send(Reply@3, {ok, Ids}),
gleam@otp@actor:continue(Items@3)
end end
),
gleam@otp@actor:start(_pipe@1).
-file("src/distribute/registry/actor.gleam", 100).
?DOC(
" Create a `ChildSpecification` for use with `gleam_otp` supervisors.\n"
"\n"
" Example:\n"
"\n"
" children: [distribute/registry/actor.child_spec()]\n"
).
-spec child_spec() -> gleam@otp@supervision:child_specification(gleam@erlang@process:subject(registry_command())).
child_spec() ->
gleam@otp@supervision:worker(fun() -> start_link() end).