glyn/pubsub
Glyn PubSub - Type-Safe Distributed Event Streaming
This module provides a type-safe wrapper around Erlang’s syn PubSub system,
enabling distributed event streaming and one-to-many message broadcasting with
compile-time type safety.
Actor Integration Pattern
PubSub works seamlessly with Gleam’s actor system using the selector pattern:
import gleam/otp/actor
pub type ChatActorMessage {
GetMessageCount(reply_with: Subject(Int))
ChatEvent(ChatMessage)
ChatActorShutdown
}
fn start_chat_actor(
pubsub: pubsub.PubSub(ChatMessage),
group: String,
) -> Result(actor.Started(Subject(ChatActorMessage)), actor.StartError) {
actor.new_with_initialiser(5000, fn(subject) {
let subscription = pubsub.subscribe(pubsub, group, process.self())
let selector =
process.new_selector()
|> process.select(subject)
|> process.select_map(subscription.subject, ChatEvent)
let initial_state = ChatActorState(message_count: 0, last_message: "")
actor.initialised(initial_state)
|> actor.selecting(selector)
|> actor.returning(subject)
|> Ok
})
|> actor.on_message(handle_chat_message)
|> actor.start()
}
Types
Subscription handle for cleanup
pub type Subscription(message, group) {
Subscription(
pubsub: PubSub(message),
group: group,
subject: process.Subject(message),
subscriber_pid: process.Pid,
)
}
Constructors
-
Subscription( pubsub: PubSub(message), group: group, subject: process.Subject(message), subscriber_pid: process.Pid, )
Values
pub fn new(
scope scope: String,
message_type message_type: glyn.MessageType(message),
) -> PubSub(message)
Create a new type-safe PubSub system with a message type for deterministic type identification The message_type should be a MessageType that uniquely identifies the message type
pub fn publish(
pubsub: PubSub(message),
group: group,
message: message,
) -> Int
Publish a type-safe message to all subscribers of a group
pub fn subscribe(
pubsub: PubSub(message),
group: group,
subscriber_pid: process.Pid,
) -> Subscription(message, group)
Subscribe to a PubSub group and return a type-safe Subject
pub fn subscribers(
pubsub: PubSub(message),
group: String,
) -> List(process.Pid)
Get list of subscriber PIDs for a group (useful for debugging)
pub fn unsubscribe(
subscription: Subscription(message, group),
) -> Nil
Unsubscribe from a PubSub group