OMQ.beam
BEAM bindings for OMQ, backed by omq-tokio.
Erlang is the base binding. Elixir and Gleam are thin wrappers over the same Erlang module and NIF, so one Rust native library serves all three languages.
Architecture detail: doc/architecture.md.
Benchmarks compare the three OMQ wrappers against erlzmq and chumak.
exzmq is not included because its current public API is CLIENT/SERVER-only.
Install
Erlang:
{deps, [{omq, "0.1.0"}]}.
Elixir:
def deps do
[{:omq_elixir, "~> 0.1"}]
end
Gleam:
[dependencies]
omq_gleam = ">= 0.1.0 and < 1.0.0"
API Shape
omq:context(...)owns native IO threads and creates sockets.- Erlang is the base API. Elixir and Gleam wrappers keep the same native
context and
inproc://namespace through explicit share keys. - Socket resources cover all 20 ZMQ socket types and use normal endpoint strings for bind/connect.
- Message calls support binaries, strings, Erlang terms, JSON, multipart, and nonblocking variants.
- Pub/sub controls, RADIO/DISH groups, polling, monitoring, proxies, and core libzmq-compatible options are exposed through the Erlang module.
- Treat each socket as owned by one BEAM process. This matches actor-style sequencing and keeps multipart frame state local to the caller.
- Create more sockets for more concurrent flows; share contexts when wrappers
need the same
inproc://namespace.
Example:
{ok, Ctx} = omq:context(),
{ok, Pull} = omq:socket(Ctx, pull),
{ok, Push} = omq:socket(Ctx, push),
{ok, Endpoint} = omq:bind(Pull, <<"tcp://127.0.0.1:0">>),
ok = omq:connect(Push, Endpoint),
ok = omq:send(Push, <<"hello">>),
{ok, <<"hello">>} = omq:recv(Pull, 1000),
ok = omq:close(Push),
ok = omq:close(Pull),
ok = omq:term(Ctx).
Development commands: DEVELOPMENT.md.