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@cluster@gossip.erl
-module(distribute@cluster@gossip).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/distribute/cluster/gossip.gleam").
-export([local_view/0, send_to/2, receive_and_merge/1, merge_single/1, pick_random_peers/2]).
-export_type([node_status/0, gossip_entry/0, gossip_message/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 node_status() :: alive | suspect | dead.
-type gossip_entry() :: {gossip_entry,
binary(),
node_status(),
integer(),
integer()}.
-type gossip_message() :: {gossip_message, list(gossip_entry())}.
-file("src/distribute/cluster/gossip.gleam", 60).
?DOC(" Get the local gossip view as a list of entries.\n").
-spec local_view() -> list(gossip_entry()).
local_view() ->
Raw = gossip_ffi:local_view(),
gleam@list:map(
Raw,
fun(Item) ->
{Node, Status_str, Inc, Ts} = Item,
Status = case Status_str of
<<"alive"/utf8>> ->
alive;
<<"suspect"/utf8>> ->
suspect;
_ ->
dead
end,
{gossip_entry, Node, Status, Inc, Ts}
end
).
-file("src/distribute/cluster/gossip.gleam", 74).
?DOC(" Convert a status to string for FFI.\n").
-spec status_to_string(node_status()) -> binary().
status_to_string(Status) ->
case Status of
alive ->
<<"alive"/utf8>>;
suspect ->
<<"suspect"/utf8>>;
dead ->
<<"dead"/utf8>>
end.
-file("src/distribute/cluster/gossip.gleam", 83).
?DOC(" Send gossip to a specific node.\n").
-spec send_to(binary(), list(gossip_entry())) -> nil.
send_to(Node, Entries) ->
Raw = gleam@list:map(
Entries,
fun(E) ->
{erlang:element(2, E),
status_to_string(erlang:element(3, E)),
erlang:element(4, E),
erlang:element(5, E)}
end
),
gossip_ffi:send_gossip(Node, Raw).
-file("src/distribute/cluster/gossip.gleam", 92).
?DOC(" Receive and merge gossip from a peer.\n").
-spec receive_and_merge(list(gossip_entry())) -> nil.
receive_and_merge(Entries) ->
Raw = gleam@list:map(
Entries,
fun(E) ->
{erlang:element(2, E),
status_to_string(erlang:element(3, E)),
erlang:element(4, E),
erlang:element(5, E)}
end
),
gossip_ffi:receive_gossip(Raw).
-file("src/distribute/cluster/gossip.gleam", 102).
?DOC(
" Merge a single entry into the local view.\n"
" Uses the rule: higher incarnation wins; on tie, alive > suspect > dead.\n"
).
-spec merge_single(gossip_entry()) -> nil.
merge_single(Entry) ->
gossip_ffi:merge_entry(
erlang:element(2, Entry),
status_to_string(erlang:element(3, Entry)),
erlang:element(4, Entry),
erlang:element(5, Entry)
).
-file("src/distribute/cluster/gossip.gleam", 112).
?DOC(" Pick random peers from a list of nodes.\n").
-spec pick_random_peers(list(binary()), integer()) -> list(binary()).
pick_random_peers(Nodes, Count) ->
gleam@list:take(Nodes, Count).