ElixirKit.PubSub
(elixirkit v0.1.0)
Copy Markdown
Publish/Subscribe server to exchange messages between Elixir and native code.
PubSub is designed to be started alongside elixirkit::PubSub from a native app.
Subscribes and broadcasts are always unidirectional, that is, an Elixir process will not receive their own broadcasts.
See start_link/1 for an example.
Summary
Functions
Broadcasts a message on the given topic to the Rust side.
Returns a specification to start PubSub under a supervisor.
Starts PubSub and links it to the current process.
Subscribes the caller to messages on the given topic from the Rust side.
Types
Functions
Broadcasts a message on the given topic to the Rust side.
@spec child_spec(keyword()) :: Supervisor.child_spec()
Returns a specification to start PubSub under a supervisor.
Options
:significant- a boolean indicating if the child process should be considered significant with regard to automatic shutdown. Defaults tofalse.
Remaining options are the same as in start_link/1.
@spec start_link(keyword()) :: GenServer.on_start()
Starts PubSub and links it to the current process.
Options
:connect- how to connect to the native side. Can be one of::ignore- don't start the server.a URL - e.g.
"tcp://127.0.0.1:12345".
elixirkit::elixirand friends set theELIXIRKIT_PUBSUBenvironment variable, so a common pattern isconnect: System.get_env("ELIXIRKIT_PUBSUB") || :ignore.:on_exit- a zero-arity function called when PubSub exits (e.g. when the native side disconnects).Handling exit
It is recommended to set
on_exit: &System.stop/0to cleanly shutdown the VM when the native side exits abruptly.Alternatively, consider monitoring the
ElixirKit.PubSubprocess and respond accordingly.Finally, you may instead set
{ElixirKit.PubSub, ..., significant: true}in your supervision tree and set your supervisor toauto_shutdown: :any_significant | :all_significant.
Examples
defmodule Server do
use GenServer
@impl true
def init(_) do
ElixirKit.PubSub.subscribe("messages")
ElixirKit.PubSub.broadcast("messages", "ready")
{:ok, %{}}
end
@impl true
def handle_info(message, state) do
dbg(message)
{:noreply, state}
end
end
children = [
{ElixirKit.PubSub,
connect: System.fetch_env!("ELIXIRKIT_PUBSUB"),
on_exit: fn -> System.stop() end},
Server
]
{:ok, _} = Supervisor.start_link(children, strategy: :one_for_one)
@spec subscribe(topic()) :: :ok
Subscribes the caller to messages on the given topic from the Rust side.