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

Type-safe PubSub wrapper

pub opaque type PubSub(message)

Subscription handle for cleanup

pub type Subscription(message, group) {
  Subscription(
    pubsub: PubSub(message),
    group: group,
    subject: process.Subject(message),
    subscriber_pid: process.Pid,
  )
}

Constructors

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

Search Document