Current section
Files
Jump to
Current section
Files
src/glixir@pubsub.erl
-module(glixir@pubsub).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glixir/pubsub.gleam").
-export([start/1, subscribe/4, subscribe_with_registry_key/5, broadcast/4, unsubscribe/2, string_encoder/1, string_decoder/1, int_encoder/1, int_decoder/1]).
-export_type([pub_sub/1, pub_sub_error/0, pub_sub_start_result/0, pub_sub_subscribe_result/0, pub_sub_broadcast_result/0, pub_sub_unsubscribe_result/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(
"\n"
" This module provides a *phantom-typed* interface to Phoenix PubSub.\n"
" All PubSub systems are parameterized by their `message_type`,\n"
" and use JSON serialization for type-safe cross-process communication.\n"
"\n"
" IMPORTANT: PubSub names must be pre-existing atoms to prevent atom table overflow.\n"
" Users are responsible for creating atoms safely before calling start().\n"
).
-opaque pub_sub(EUR) :: {pub_sub, gleam@erlang@process:pid_()} |
{gleam_phantom, EUR}.
-type pub_sub_error() :: {start_error, binary()} |
{subscribe_error, binary()} |
{broadcast_error, binary()} |
{unsubscribe_error, binary()} |
{encode_error, binary()} |
{decode_error, binary()}.
-type pub_sub_start_result() :: {pubsub_start_ok, gleam@erlang@process:pid_()} |
{pubsub_start_error, gleam@dynamic:dynamic_()}.
-type pub_sub_subscribe_result() :: pubsub_subscribe_ok |
{pubsub_subscribe_error, gleam@dynamic:dynamic_()}.
-type pub_sub_broadcast_result() :: pubsub_broadcast_ok |
{pubsub_broadcast_error, gleam@dynamic:dynamic_()}.
-type pub_sub_unsubscribe_result() :: pubsub_unsubscribe_ok |
{pubsub_unsubscribe_error, gleam@dynamic:dynamic_()}.
-file("src/glixir/pubsub.gleam", 100).
?DOC(
" Start a phantom-typed PubSub system with bounded message types\n"
" \n"
" IMPORTANT: The atom must already exist to prevent atom table overflow.\n"
" Use atom.create_from_string() or atom.from_string() safely before calling this.\n"
).
-spec start(gleam@erlang@atom:atom_()) -> {ok, pub_sub(any())} |
{error, pub_sub_error()}.
start(Name) ->
glixir@utils:debug_log_with_prefix(
debug,
<<"pubsub"/utf8>>,
<<"Starting PubSub: "/utf8, (erlang:atom_to_binary(Name))/binary>>
),
case 'Elixir.Glixir.PubSub':start(Name) of
{pubsub_start_ok, Pid} ->
glixir@utils:debug_log_with_prefix(
info,
<<"pubsub"/utf8>>,
<<"PubSub started successfully"/utf8>>
),
{ok, {pub_sub, Pid}};
{pubsub_start_error, Reason} ->
glixir@utils:debug_log_with_prefix(
error,
<<"pubsub"/utf8>>,
<<"PubSub start failed"/utf8>>
),
{error, {start_error, gleam@string:inspect(Reason)}}
end.
-file("src/glixir/pubsub.gleam", 130).
?DOC(
" Subscribe to a topic with message handling\n"
" The gleam_function must accept a single String parameter (JSON) and return Nil\n"
" Subscribe to a topic with message handling\n"
).
-spec subscribe(gleam@erlang@atom:atom_(), binary(), binary(), binary()) -> {ok,
nil} |
{error, pub_sub_error()}.
subscribe(Pubsub_name, Topic, Gleam_module, Gleam_function) ->
glixir@utils:debug_log_with_prefix(
debug,
<<"pubsub"/utf8>>,
<<"Subscribing to topic: "/utf8, Topic/binary>>
),
case 'Elixir.Glixir.PubSub':subscribe(
Pubsub_name,
Topic,
Gleam_module,
Gleam_function
) of
pubsub_subscribe_ok ->
glixir@utils:debug_log_with_prefix(
info,
<<"pubsub"/utf8>>,
<<"Subscribed successfully to: "/utf8, Topic/binary>>
),
{ok, nil};
{pubsub_subscribe_error, Reason} ->
glixir@utils:debug_log_with_prefix(
error,
<<"pubsub"/utf8>>,
<<"Subscribe failed for topic: "/utf8, Topic/binary>>
),
{error, {subscribe_error, gleam@string:inspect(Reason)}}
end.
-file("src/glixir/pubsub.gleam", 163).
?DOC(" Subscribe to a topic with registry key for direct actor targeting\n").
-spec subscribe_with_registry_key(
gleam@erlang@atom:atom_(),
binary(),
binary(),
binary(),
binary()
) -> {ok, nil} | {error, pub_sub_error()}.
subscribe_with_registry_key(
Pubsub_name,
Topic,
Gleam_module,
Gleam_function,
Registry_key
) ->
glixir@utils:debug_log_with_prefix(
debug,
<<"pubsub"/utf8>>,
<<<<<<"Subscribing to topic: "/utf8, Topic/binary>>/binary,
" with key: "/utf8>>/binary,
Registry_key/binary>>
),
case 'Elixir.Glixir.PubSub':subscribe(
Pubsub_name,
Topic,
Gleam_module,
Gleam_function,
Registry_key
) of
pubsub_subscribe_ok ->
glixir@utils:debug_log_with_prefix(
info,
<<"pubsub"/utf8>>,
<<<<<<"Subscribed successfully to: "/utf8, Topic/binary>>/binary,
" with key: "/utf8>>/binary,
Registry_key/binary>>
),
{ok, nil};
{pubsub_subscribe_error, Reason} ->
glixir@utils:debug_log_with_prefix(
error,
<<"pubsub"/utf8>>,
<<"Subscribe failed for topic: "/utf8, Topic/binary>>
),
{error, {subscribe_error, gleam@string:inspect(Reason)}}
end.
-file("src/glixir/pubsub.gleam", 205).
?DOC(" Broadcast a message to all subscribers using JSON serialization\n").
-spec broadcast(
gleam@erlang@atom:atom_(),
binary(),
EVE,
fun((EVE) -> binary())
) -> {ok, nil} | {error, pub_sub_error()}.
broadcast(Pubsub_name, Topic, Message, Encode) ->
glixir@utils:debug_log_with_prefix(
debug,
<<"pubsub"/utf8>>,
<<"Broadcasting to topic: "/utf8, Topic/binary>>
),
Json_message = Encode(Message),
case 'Elixir.Glixir.PubSub':broadcast(Pubsub_name, Topic, Json_message) of
pubsub_broadcast_ok ->
glixir@utils:debug_log_with_prefix(
info,
<<"pubsub"/utf8>>,
<<"Broadcast successful to: "/utf8, Topic/binary>>
),
{ok, nil};
{pubsub_broadcast_error, Reason} ->
glixir@utils:debug_log_with_prefix(
error,
<<"pubsub"/utf8>>,
<<"Broadcast failed for topic: "/utf8, Topic/binary>>
),
{error, {broadcast_error, gleam@string:inspect(Reason)}}
end.
-file("src/glixir/pubsub.gleam", 241).
?DOC(" Unsubscribe from a topic\n").
-spec unsubscribe(gleam@erlang@atom:atom_(), binary()) -> {ok, nil} |
{error, pub_sub_error()}.
unsubscribe(Pubsub_name, Topic) ->
glixir@utils:debug_log_with_prefix(
debug,
<<"pubsub"/utf8>>,
<<"Unsubscribing from topic: "/utf8, Topic/binary>>
),
case 'Elixir.Glixir.PubSub':unsubscribe(Pubsub_name, Topic) of
pubsub_unsubscribe_ok ->
glixir@utils:debug_log_with_prefix(
info,
<<"pubsub"/utf8>>,
<<"Unsubscribed successfully from: "/utf8, Topic/binary>>
),
{ok, nil};
{pubsub_unsubscribe_error, Reason} ->
glixir@utils:debug_log_with_prefix(
error,
<<"pubsub"/utf8>>,
<<"Unsubscribe failed for topic: "/utf8, Topic/binary>>
),
{error, {unsubscribe_error, gleam@string:inspect(Reason)}}
end.
-file("src/glixir/pubsub.gleam", 271).
?DOC(" JSON encoder for String messages\n").
-spec string_encoder(binary()) -> binary().
string_encoder(Message) ->
_pipe = gleam@json:string(Message),
gleam@json:to_string(_pipe).
-file("src/glixir/pubsub.gleam", 276).
?DOC(" JSON decoder for String messages\n").
-spec string_decoder(binary()) -> {ok, binary()} | {error, binary()}.
string_decoder(Json_string) ->
case gleam@json:parse(
Json_string,
{decoder, fun gleam@dynamic@decode:decode_string/1}
) of
{ok, Message} ->
{ok, Message};
{error, _} ->
{error, <<"Failed to decode string from JSON"/utf8>>}
end.
-file("src/glixir/pubsub.gleam", 284).
?DOC(" JSON encoder for Int messages\n").
-spec int_encoder(integer()) -> binary().
int_encoder(Message) ->
_pipe = gleam@json:int(Message),
gleam@json:to_string(_pipe).
-file("src/glixir/pubsub.gleam", 289).
?DOC(" JSON decoder for Int messages\n").
-spec int_decoder(binary()) -> {ok, integer()} | {error, binary()}.
int_decoder(Json_string) ->
case gleam@json:parse(
Json_string,
{decoder, fun gleam@dynamic@decode:decode_int/1}
) of
{ok, Message} ->
{ok, Message};
{error, _} ->
{error, <<"Failed to decode int from JSON"/utf8>>}
end.