Migration & Releases
Release process
Section titled “Release process”beryl uses a fully automated release pipeline:
- Changelog fragments are authored with
changie new(orjust change) and committed alongside the code change. Fragments live in.changes/unreleased/until a release is cut. - changie-release collects unreleased fragments, bumps the version in
gleam.toml, and opens a release PR. - Merging the release PR triggers
auto-tag, which creates a GitHub release and the version tag. - The
publishworkflow fires on the tag and publishes the new version to Hex.pm.
Where to find changelogs:
- GitHub Releases — the canonical per-version changelog
.changes/unreleased/in the repository — what is staged for the next release
Recent notable changes
Section titled “Recent notable changes”The following changes have accumulated since the last release. They are described at a high level here; see GitHub for exact signatures.
send_info and with_handle_info
Section titled “send_info and with_handle_info”Channels can now receive server-originated OTP messages. Add a handle_info callback with channel.with_handle_info/2, then deliver messages from anywhere using beryl.send_info/4. A Reply returned from handle_info becomes a push (no client ref exists, so no phx_reply is sent).
Phoenix presence diff broadcasting
Section titled “Phoenix presence diff broadcasting”beryl.broadcast_presence_diff/3 sends Phoenix-shaped presence diffs — joins/leaves objects keyed by presence key with metas arrays. Local track and untrack operations also invoke on_diff with concrete diff values. Anonymous entries are excluded from encoded diffs.
Segment-aware topic wildcards
Section titled “Segment-aware topic wildcards”topic.parse_pattern/1 now recognises multi-segment wildcard patterns like "document:*:*". Use topic.extract_wildcards/2 to pull out the matched segments. Single trailing * patterns retain existing prefix-wildcard behaviour.
Mist direct transport
Section titled “Mist direct transport”The core WebSocket transport now uses Mist directly instead of Wisp. If your application used beryl/transport/wisp, migrate to beryl/transport/mist. Examples also use Mist for HTTP routing and static assets. See the WebSocket Transport guide for the updated setup.
PubSub socket exclusion fix
Section titled “PubSub socket exclusion fix”broadcast_from now correctly excludes the originating socket when a channel is PubSub-enabled. Previously, broadcasts through PubSub could echo back to the sender.
Rate limiter fail-closed
Section titled “Rate limiter fail-closed”The rate limiter now denies requests when the token bucket actor cannot be started, rather than silently allowing them through. If you rely on rate limiting for security, this change removes a potential bypass under resource exhaustion.
Removed: socket.topics() and socket.is_subscribed()
Section titled “Removed: socket.topics() and socket.is_subscribed()”These functions always returned empty/false because subscriptions are tracked internally by the coordinator. They have been removed from the public API.
Removed: info type parameter on Channel
Section titled “Removed: info type parameter on Channel”Channel was simplified from Channel(assigns, info) to Channel(assigns). with_handle_info wires the callback onto the channel definition; send_info/4 delivers messages to it at runtime. The two are complementary — use with_handle_info when building the channel and send_info when dispatching a message to it.
WebSocket authentication hook
Section titled “WebSocket authentication hook”The Mist transport config now accepts an on_connect callback. Return Error(Nil) to reject the upgrade with a 403 before the WebSocket handshake completes.
Upgrading
Section titled “Upgrading”When upgrading across a minor version boundary:
- Read the GitHub Release notes for the target version.
- Check removed or changed exports against the module map.
- Run
gleam check— the Gleam compiler will surface type mismatches caused by API changes. - Run
just testto verify runtime behaviour.
If you hit a regression not covered by the release notes, please open an issue.