Skip to content

HappiHacking/gnomeqtt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gnomeqtt

A minimal MQTT 3.1.1 broker written in Elixir, built as the running example for the HappiHacking BEAM for Developers workshop.

Every BEAM concept in the workshop — processes, messages, memory, scheduling, supervision, observability, patterns — maps onto a concrete component in this broker. The code is deliberately small and readable so students can trace a packet from TCP socket to subscriber and back.

What's here

  • Full MQTT 3.1.1 broker (CONNECT, PUBLISH, SUBSCRIBE, UNSUBSCRIBE, PING, DISCONNECT, will messages)
  • QoS 0 and QoS 1 (QoS 2 is a workshop extension exercise)
  • Retained messages, clean-session persistence, offline queues
  • Authentication as pure-function gatekeeper
  • Topic wildcards (+, #) including the $-system-topic privacy rule

Architecture

Application (supervision tree)
├── Registry            tracks Sessions by client_id
├── RetainedStore       last message per topic (GenServer + ETS)
├── TopicRouter         subscription registry + fan-out
├── SessionSupervisor   DynamicSupervisor
├── ConnectionSupervisor DynamicSupervisor
└── Listener            TCP accept loop (Task)

Per client:
  Connection (GenServer) ←TCP→ MQTT client
       ↕ Elixir messages
  Session (GenServer) — subscriptions, offline queue, will
       ↕ Elixir messages
  TopicRouter → broadcasts to matching subscribers

Walkthroughs and anti-pattern review live in docs/.

Running

mix deps.get
iex -S mix

Broker listens on port 1883 by default. Connect with any MQTT client:

mosquitto_sub -h localhost -t "sensors/#" -v
mosquitto_pub -h localhost -t "sensors/temp" -m "22.5"

Configure port or auth in config/config.exs:

config :gnomeqtt,
  port: 1883,
  auth: [{"user", "pass"}]  # or nil for no auth

Tests

mix test

Workshop exercises

Five planted issues live on their own branches. Each has an EXERCISE.md explaining the problem and how to observe it:

  • exercise/unbounded-queue — Session offline queue has no cap
  • exercise/binary-leak — TopicRouter accumulates ProcBin references
  • exercise/bottleneck — every publish serializes through one TopicRouter
  • exercise/missing-supervision — Connections and Sessions run unsupervised
  • exercise/god-process — Connection and Session merged into one process

Check one out and compare with main to see the fix:

git checkout exercise/unbounded-queue
cat EXERCISE.md
# ... investigate, propose a fix ...
git diff main -- lib/gnomeqtt/session.ex

Status

Reference implementation for teaching. Not production-ready — there is no QoS 2, no TLS, no persistence across broker restarts, and the TopicRouter is intentionally a single-process bottleneck.

License

MIT. See LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages