A Linda tuple space for the BEAM. Processes coordinate by writing tuples into a shared store and reading them by pattern rather than by address — so a producer never learns who consumed its work, a consumer never learns who produced it, and neither has to be alive at the same moment as the other.
# somewhere
Tuplex.out({:job, 17, "resize thumbnails"})
# somewhere else, possibly later, possibly on a process that did not exist yet
{:ok, {:job, id, task}} = Tuplex.in({:job, :_, :_})Highlights
The Linda operations — out/1, in/2, rd/2, inp/2, rdp/1, rd_all/1, with take/2 as an alias for callers who would rather not qualify the operator name.
Leases — the departure from classical Linda. in/2 and inp/2 accept lease: :monitor or lease: {:monitor, :ack}, holding a tuple against the consuming process rather than removing it. A consumer that dies without finishing returns the tuple to the space instead of destroying it. ack/1 releases an acknowledged lease.
Standing subscriptions. watch/2 and unwatch/1 observe :out, :in and :requeue without consuming, and survive shard restarts. Lossy under backpressure, by design.
eval/1 computes a tuple's contents in a fresh process.
Telemetry across the surface, with spans on in/2 and rd/2 and a periodic [:tuplex, :shard, :stats] per shard. The event vocabulary is documented in Tuplex.Telemetry and is stable in the same sense as the public API.
Install
def deps do
[{:tuplex, "~> 0.1.0"}]
endWorth knowing before you reach for it
This is not a job queue. If you already know who does the work and when, Oban, Broadway, Phoenix.PubSub or a plain GenServer will serve you better — the README has a table. Tuplex earns its place only where the coordination is genuinely anonymous and shape-driven.
- Everything is in memory. A node restart is an empty space; there is no persistence.
- Single-node.
inp/2's exactness is shard-local — it rests on one process per tag serialising its own destructive reads, and would not survive unchanged into a distributed version. :_can be stored but never selected specifically, since:_in a template is the wildcard. Documented as a limitation rather than rejected, because rejecting it correctly would mean a deep term walk on every write.
Only the Tuplex module is public API. Tuplex.Store and Tuplex.Template are published for reference but are not covered by semantic versioning.
Full notes in the CHANGELOG.