qumo

command module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README ΒΆ

qumo

CI Go Report Card License

qumo is a high-performance Media over QUIC (MoQ) relay server with peer-based content discovery, enabling distributed media streaming over the QUIC transport protocol.

Features

  • πŸš€ High-Performance Relay: Built on QUIC for low-latency media streaming
  • πŸ“‘ MoQT Protocol: Full Media over QUIC Transport support (moq-lite draft-04)
  • πŸ”— Peer-Based Topology: Relays connect to each other via ANNOUNCE_PLEASE for decentralized content discovery
  • πŸ“Š Observability: Prometheus metrics, health probes, and status APIs
  • πŸ”’ TLS Security: Built-in TLS 1.3 support for encrypted connections
  • 🐳 Docker-Support: Env-var zero-config; prebuilt multi-arch images on GHCR (ghcr.io/qumo-dev/qumo)

Installation

Option 1: Install via Go
go install github.com/qumo-dev/qumo@latest
Option 2: Download Binary

Download the latest archive from GitHub Releases:

# Linux/macOS
curl -L https://github.com/qumo-dev/qumo/releases/latest/download/qumo_0.4.0_linux_amd64.tar.gz | tar xz
./qumo playground      # one-command demo: relay + web UI at http://127.0.0.1:8080

# Or for a standalone relay:
mage cert              # generate a dev cert (mkcert or self-signed)
./qumo relay           # start the relay (certs/server.crt + .key)

# Windows: download qumo_0.4.0_windows_amd64.zip from the releases page
Option 3: Docker

See docker/README.md for compose examples, GHCR usage, and deployment options.

Option 4: Build from Source
git clone https://github.com/qumo-dev/qumo.git
cd qumo
mage build        # builds bin/qumo with version info
# or: go build -o qumo .

Usage

qumo relay       # Start MoQ relay server (QUIC/MoQT, WebTransport, peer mesh)
qumo rtmp        # Start RTMP ingest server (bridges RTMP β†’ MoQT)
qumo rtsp        # Pull from an RTSP source (e.g. IP camera) and republish as MoQT
qumo rtsp-push   # Start the RTSP push ingest server (bridges RTSP β†’ MoQT)
qumo playground  # One-command local demo: in-process relay + embedded web UI on http://127.0.0.1:8080
qumo loadgen     # Out-of-process capacity load generator (publish|subscribe) β€” see Benchmarking
qumo version     # Print build-time version info

For environment variables and configuration, see relay-config.example.env. For Docker-based deployment, see docker/README.md.

Architecture

System Overview
graph LR
    Publisher["Publisher<br/>(Browser/WebTransport)"]
    Hub["Hub Relay<br/>(qumo relay)"]
    EdgeA["Edge Relay A<br/>(qumo relay)"]
    EdgeB["Edge Relay B<br/>(qumo relay)"]
    Subscriber["Subscriber<br/>(Browser/WebTransport)"]

    Publisher -->|"QUIC/MoQ<br/>WebTransport"| EdgeA
    EdgeA <-->|"ANNOUNCE_PLEASE<br/>QUIC peer"| Hub
    Hub <-->|"ANNOUNCE_PLEASE<br/>QUIC peer"| EdgeB
    EdgeB -->|"QUIC/MoQ<br/>WebTransport"| Subscriber
Peer Discovery

On startup, each relay discovers peers through one or more PeerResolver implementations:

  1. Static peers (PEERS): dial each address directly and maintain the connection.
  2. Nomad native discovery (within-cluster): automatically discovers peers within the same Nomad cluster via the Nomad service API. Edges discover all local hubs; hubs discover nothing locally (no local hub↔hub connections).
  3. Remote resolver (cross-cluster, optional): queries an external traffic resolver API (e.g. qumo-enterprise) for cross-cluster hub discovery. Hubs discover remote hubs; edges never query the remote resolver.

Each connection dials QUIC with ALPN moqt, exchanges ANNOUNCE_PLEASE / ANNOUNCE, and registers the peer's tracks on the local TrackMux. On disconnect the connection is retried after 5 s.

graph TD
    Start["Relay Startup"]

    Start -->|"for each PEER"| ALPN
    Start -->|"Nomad API (within-cluster)"| Resolve["PeerResolver.ResolvePeers"]
    Start -->|"Remote resolver (cross-cluster)"| Resolve

    Resolve -->|"returned peer list"| ALPN

    ALPN["QUIC dial (ALPN: moq-lite-04)"] --> Announce["ANNOUNCE_PLEASE / ANNOUNCE"]
    Announce --> TrackMux["Register tracks on local TrackMux"]
    TrackMux --> Serve["Serve subscribers"]

    ALPN -->|"failed"| Retry["Wait 5s β†’ retry"]
    Serve -->|"disconnected"| Retry
    Retry --> ALPN

Development

Requirements
  • Go 1.26+ β€” Download or use your package manager
  • Deno (required for mage build; the Go binary embeds the web UI built by Deno + Vite) β€” Download
  • Mage β€” Build automation tool
    go install github.com/magefile/mage@latest
    
    Then run mage help to see all available tasks.

For complete Mage documentation and all available targets, see magefiles/README.md.

Project Structure
qumo/
β”œβ”€β”€ docker/                     # Docker artifacts & docs
β”‚   β”œβ”€β”€ Dockerfile              # Multi-stage container build
β”‚   β”œβ”€β”€ docker-compose.yml               # Single relay (local build)
β”‚   β”œβ”€β”€ docker-compose.external.yml      # Single relay (GHCR prebuilt)
β”‚   β”œβ”€β”€ docker-compose.static.yml        # 3-region topology, static PEERS (no discovery)
β”‚   β”œβ”€β”€ docker-compose.nomad.yml         # Single-region Nomad cluster (LocalResolver)
β”‚   β”œβ”€β”€ nomad/                           # Nomad agent config + job spec
β”‚   └── README.md               # Docker usage guide
β”‚
β”œβ”€β”€ internal/                   # Core implementation
β”‚   β”œβ”€β”€ relay/                  # Relay server (handlers, peer resolvers, caching, credential auth)
β”‚   β”œβ”€β”€ ingest/                 # RTMP & RTSP ingest (push + pull), codec init-data builders
β”‚   β”œβ”€β”€ rtmp/                   # RTMP protocol stack
β”‚   β”œβ”€β”€ rtsp/                   # RTSP protocol stack & RTP de-packetization
β”‚   β”œβ”€β”€ playground/             # One-command demo server (relay + embedded web UI + /api/pull)
β”‚   β”œβ”€β”€ loadgen/                # Out-of-process capacity load generator (qumo loadgen)
β”‚   β”œβ”€β”€ cors/                   # WebTransport origin validation (CSWT mitigation)
β”‚   β”œβ”€β”€ smoketest/              # Cross-region streaming smoke test harness
β”‚   └── version/                # Version info
β”‚
β”œβ”€β”€ magefiles/                  # Build automation (Mage tasks)
β”‚
β”œβ”€β”€ scripts/                    # Bench dashboard generator (Deno)
β”œβ”€β”€ tools/capacity/             # Capacity driver: sweeps/ceiling-finds by driving `qumo loadgen`
β”œβ”€β”€ tools/paramexp/             # Parameter-space explorer (GP surrogate; separate module)
β”œβ”€β”€ docs/                       # Design docs
β”œβ”€β”€ playground/                 # Web demo / relay test client (Deno + Solid)
β”œβ”€β”€ .github/workflows/          # CI/CD pipelines
β”œβ”€β”€ go.mod & go.sum             # Go dependencies
└── main.go                     # Entry point (CLI dispatch)
Build System (Mage)

See magefiles/README.md for the complete reference. Common targets:

mage build         # Build binary to bin/qumo
mage test          # Run tests
mage check         # Format, vet, and test
mage lint          # Run golangci-lint
mage docker:build  # Build Docker image
mage relay         # Run relay server locally
mage smoke         # Run cross-region streaming smoke test
Benchmarking & capacity

The relay's benchmarks emit JSONL that a zero-dependency Deno tool turns into a single, self-contained dashboard β€” open one file, no server:

# After a bench run has written results.jsonl into <dir> (BENCH_RESULTS_DIR):
deno run --allow-read=<dir> --allow-write=<dir> scripts/relay_bench_report.ts <dir>
# β†’ <dir>/index.html : capacity headline + decision summary + every plot inline,
#   plus the paramexp GP/ML findings when passed --paramexp <report-dir>.

Concurrent-session capacity is measured out-of-process. Running the relay and the load clients in one process makes client-side QUIC-handshake CPU β€” not the relay β€” the bottleneck, so the load runs against a separately running relay and the measurement reports the relay's own per-session cost by scraping its /metrics (go_goroutines, process_resident_memory_bytes, qumo_relay_sessions_active) before/after the run.

The qumo loadgen CLI is two small primitives β€” pure remote clients that dial the relay you point them at and never spawn one:

qumo loadgen publish       --relay <host:4433> --ca <cert.pem>              # trickle source
qumo loadgen subscribe --relay <host:4433> --ca <cert.pem> --hold 15s 12000 # measure N=12000

subscribe --results <dir> appends a capacity-group record to results.jsonl, which the dashboard renders.

Sweeping / finding the ceiling is orchestration, so it lives in a separate driver β€” tools/capacity β€” that composes the primitives (starts a relay + publisher, then probes session counts). Build it with go build -o capacity ./tools/capacity. It runs two ways:

  • One box: --start-relay spawns a local relay (self-signed cert generated in-process β€” no openssl) pinned via --relay-cores so its CPU is isolated from the load β€” a single-box stand-in for two hosts. A fresh relay is started per probe, so each measurement is independent and never inherits residual state from a prior overload. --sessions probes an explicit list; --auto climbs until the relay can't hold to find the ceiling (--bisect pins the boundary). This is what the capacity-sweep job in .github/workflows/bench-relay.yml runs:

    ./capacity --start-relay --relay-cores 0-1 --sessions "500 1000 2000" --hold 10s
    ./capacity --start-relay --relay-cores 0-1 --auto --start 2000 --max 50000 --bisect
    
  • Two hosts: point it at a relay running elsewhere; it only generates load:

    ./capacity --relay relay.example.net:4433 --ca cert.pem --auto --start 5000 --max 30000
    

Every probe appends to results.jsonl, so a run renders in the same dashboard. A distributed (multi-machine) run is what a 25K-session ceiling claim needs to be confirmed rather than extrapolated.

Documentation ΒΆ

The Go Gopher

There is no documentation for this package.

Directories ΒΆ

Path Synopsis
internal
cors
Package cors provides WebTransport origin validation (cross-site WebTransport forgery mitigation), shared by the relay and ingest servers.
Package cors provides WebTransport origin validation (cross-site WebTransport forgery mitigation), shared by the relay and ingest servers.
doctor
Package doctor implements the read-only `qumo doctor` command: it explains the relay's effective runtime configuration and offers operator guidance without mutating anything.
Package doctor implements the read-only `qumo doctor` command: it explains the relay's effective runtime configuration and offers operator guidance without mutating anything.
ffpub
Package ffpub drives ffmpeg as an RTMP publisher for integration tests.
Package ffpub drives ffmpeg as an RTMP publisher for integration tests.
gctune
Package gctune resolves and applies the qumo relay's garbage-collector target.
Package gctune resolves and applies the qumo relay's garbage-collector target.
ingest
Package ingest bridges media publish protocols (RTMP, SRT, WHIP, etc.) to MoQT.
Package ingest bridges media publish protocols (RTMP, SRT, WHIP, etc.) to MoQT.
integration
Package integration holds the reusable subscription-gate collector and evaluation logic for the OBS/ffmpeg interop tests (PRD #147, M5/M6).
Package integration holds the reusable subscription-gate collector and evaluation logic for the OBS/ffmpeg interop tests (PRD #147, M5/M6).
loadgen
Package loadgen provides two out-of-process capacity primitives that connect to a running qumo relay:
Package loadgen provides two out-of-process capacity primitives that connect to a running qumo relay:
playground
Package playground powers the `qumo playground` subcommand: a self-contained local demo that starts the relay in-process, serves the embedded web UI, and exposes runtime configuration to the browser via a /config endpoint.
Package playground powers the `qumo playground` subcommand: a self-contained local demo that starts the relay in-process, serves the embedded web UI, and exposes runtime configuration to the browser via a /config endpoint.
relay
Package relay provides the MoQT relay server for content distribution.
Package relay provides the MoQT relay server for content distribution.
rtmp
Package rtmp implements the RTMP (Real-Time Messaging Protocol) v1.0 specification for live media ingest.
Package rtmp implements the RTMP (Real-Time Messaging Protocol) v1.0 specification for live media ingest.
smoketest command
version
Package version holds build-time version metadata injected via ldflags.
Package version holds build-time version metadata injected via ldflags.
tools
capacity command
Command capacity measures a qumo relay's concurrent-session capacity by driving the `qumo loadgen` primitives.
Command capacity measures a qumo relay's concurrent-session capacity by driving the `qumo loadgen` primitives.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL