glyn/registry
Glyn Registry - Type-Safe Distributed Process Registry
This module provides a type-safe wrapper around Erlang’s syn process registry,
enabling distributed service discovery and direct process communication with
compile-time type safety.
Actor Integration Pattern
The registry works seamlessly with Gleam’s actor system and composes with PubSub:
import gleam/otp/actor
import glyn/pubsub
pub type ActorMessage {
CommandMessage(Command) // Direct commands via Registry
PubSubMessage(Event) // Events via PubSub
ActorShutdown
}
fn start_integration_actor(
registry: registry.Registry(Command, String),
pubsub: pubsub.PubSub(Event),
) -> Result(actor.Started(Subject(ActorMessage)), actor.StartError) {
actor.new_with_initialiser(5000, fn(subject) {
// Create command subject for Registry
let command_subject = process.new_subject()
let assert Ok(_registration) = registry.register(
registry, "my_service", command_subject, "service_metadata"
)
// Subscribe to PubSub events
let event_subscription = pubsub.subscribe(pubsub, "events", process.self())
// Compose both message sources
let selector =
process.new_selector()
|> process.select(subject)
|> process.select_map(command_subject, CommandMessage)
|> process.select_map(event_subscription.subject, PubSubMessage)
actor.initialised(initial_state)
|> actor.selecting(selector)
|> actor.returning(subject)
|> Ok
})
|> actor.on_message(handle_message)
|> actor.start()
}
Types
Registration handle for cleanup
pub type Registration(message, metadata) {
Registration(
registry: Registry(message, metadata),
name: String,
subject: process.Subject(message),
metadata: metadata,
)
}
Constructors
-
Registration( registry: Registry(message, metadata), name: String, subject: process.Subject(message), metadata: metadata, )
Values
pub fn call(
registry: Registry(message, metadata),
name: String,
waiting timeout: Int,
sending message_fn: fn(process.Subject(reply)) -> message,
) -> Result(reply, String)
Call a registered process and wait for a reply, similar to actor.call
pub fn lookup(
registry: Registry(message, metadata),
name: String,
) -> Result(#(process.Subject(message), metadata), String)
Look up a registered process and return a type-safe Subject with metadata
pub fn new(
scope scope: String,
message_type message_type: glyn.MessageType(message),
) -> Registry(message, metadata)
Create a new Registry system for a given scope The message_type should be a MessageType that uniquely identifies the message type
pub fn register(
registry: Registry(message, metadata),
name: String,
subject: process.Subject(message),
metadata: metadata,
) -> Result(Registration(message, metadata), String)
Register a process with a name using a caller-supplied Subject Note: Registration will replace any existing registration with the same name
pub fn send(
registry: Registry(message, metadata),
name: String,
message: message,
) -> Result(Nil, String)
Send a type-safe message to a registered process
pub fn unregister(
registration: Registration(message, metadata),
) -> Result(Nil, String)
Unregister a process