Current section
Files
Jump to
Current section
Files
src/roar.erl
-module(roar).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/roar.gleam").
-export([new/2, on/3, subscribe/2, publish/3]).
-export_type([roar/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-opaque roar(DRW) :: {roar, whisper:whisper(DRW), binary()}.
-file("src/roar.gleam", 33).
?DOC(
" Create a new distributed pub/sub router.\n"
"\n"
" - `capacity`: Maximum number of messages buffered per subscription\n"
" - `scope`: Unique identifier for this router's cluster scope. Only routers\n"
" with matching scopes will exchange messages across nodes.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let router = roar.new(capacity: 50, scope: \"chat_system\")\n"
" ```\n"
).
-spec new(integer(), binary()) -> roar(any()).
new(Capacity, Scope) ->
{roar, whisper:new(Capacity), Scope}.
-file("src/roar.gleam", 52).
?DOC(
" Register a callback function to be invoked when messages are published to a topic.\n"
"\n"
" The callback is triggered for messages published locally and from remote nodes\n"
" in the same scope. Returns a cancellation function to stop listening.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let cancel = roar.on(router, \"notifications\", fn(msg) {\n"
" io.println(\"Received: \" <> msg)\n"
" })\n"
"\n"
" // Later, stop listening\n"
" cancel()\n"
" ```\n"
).
-spec on(roar(DRZ), binary(), fun((DRZ) -> nil)) -> fun(() -> nil).
on(Roar, Topic, Listener) ->
Local_cancel = whisper:on(erlang:element(2, Roar), Topic, Listener),
Distributed_cancel = roar_ffi:on_distributed(
erlang:element(3, Roar),
Topic,
Listener
),
fun() ->
Local_cancel(),
Distributed_cancel()
end.
-file("src/roar.gleam", 87).
?DOC(
" Subscribe to a topic and receive messages through a buffered subscription.\n"
"\n"
" Messages published locally or from remote nodes in the same scope are queued\n"
" in the subscription buffer. Use the returned subscription's `receive` function\n"
" to consume messages, and `cancel` to unsubscribe.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let sub = roar.subscribe(router, \"events\")\n"
"\n"
" case sub.receive() {\n"
" Ok(message) -> io.println(\"Got: \" <> message)\n"
" Error(Nil) -> io.println(\"No messages available\")\n"
" }\n"
"\n"
" sub.cancel()\n"
" ```\n"
).
-spec subscribe(roar(DSC), binary()) -> whisper:subscription(DSC).
subscribe(Roar, Topic) ->
Sub = whisper:subscribe(erlang:element(2, Roar), Topic),
roar_ffi:subscribe_distributed(
erlang:element(3, Roar),
Topic,
erlang:element(2, Roar)
),
Sub.
-file("src/roar.gleam", 112).
?DOC(
" Publish a message to all subscribers of a topic across the cluster.\n"
"\n"
" The message is delivered to:\n"
" - All local subscribers on this node\n"
" - All subscribers on remote nodes in the same scope\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" roar.publish(router, \"alerts\", \"System maintenance in 5 minutes\")\n"
" // All subscribers across all nodes receive this message\n"
" ```\n"
).
-spec publish(roar(DSH), binary(), DSH) -> nil.
publish(Roar, Topic, Message) ->
whisper:publish(erlang:element(2, Roar), Topic, Message),
roar_ffi:publish_distributed(erlang:element(3, Roar), Topic, Message).