Packages
Typed distributed messaging for Gleam on the BEAM.
Retired package: Deprecated - The project needs to be redesigned around a much smaller and clearer core.
Current section
Files
Jump to
Current section
Files
src/distribute/groups.gleam
/// Process groups for pub/sub and worker pools.
///
/// This module wraps Erlang's `:pg` (process groups) module to provide
/// cluster-wide process grouping with join/leave/broadcast semantics.
///
/// Groups are distributed and eventually consistent. Processes can join multiple
/// groups, and groups can span multiple nodes.
pub type GroupError {
/// A group operation failed (e.g. invalid group name or internal error).
GroupFailed(String)
}
type Dynamic
pub type Pid
@external(erlang, "groups_ffi", "join")
fn join_ffi(group: String, pid: Pid) -> Dynamic
@external(erlang, "groups_ffi", "leave")
fn leave_ffi(group: String, pid: Pid) -> Dynamic
@external(erlang, "groups_ffi", "members")
fn members_ffi(group: String) -> Dynamic
@external(erlang, "groups_ffi", "broadcast")
fn broadcast_ffi(group: String, msg: a) -> Dynamic
@external(erlang, "groups_ffi", "is_ok_atom")
fn is_ok_atom(value: Dynamic) -> Bool
@external(erlang, "groups_ffi", "get_error_reason")
fn get_error_reason(value: Dynamic) -> String
@external(erlang, "groups_ffi", "unwrap_members")
fn unwrap_members(value: Dynamic) -> List(Pid)
/// Join a process to a named group.
pub fn join(group: String, pid: Pid) -> Result(Nil, GroupError) {
let res = join_ffi(group, pid)
case is_ok_atom(res) {
True -> Ok(Nil)
False -> Error(GroupFailed(get_error_reason(res)))
}
}
/// Remove a process from a named group.
pub fn leave(group: String, pid: Pid) -> Result(Nil, GroupError) {
let res = leave_ffi(group, pid)
case is_ok_atom(res) {
True -> Ok(Nil)
False -> Error(GroupFailed(get_error_reason(res)))
}
}
/// Get the list of member pids in a group.
pub fn members(group: String) -> List(Pid) {
let res = members_ffi(group)
unwrap_members(res)
}
/// Broadcast a message to all members of a group.
pub fn broadcast(group: String, msg: a) -> Result(Nil, GroupError) {
let res = broadcast_ffi(group, msg)
case is_ok_atom(res) {
True -> Ok(Nil)
False -> Error(GroupFailed(get_error_reason(res)))
}
}