# fafb-q

A high-performance centralized queue server written in Rust. Supports persistent publish-subscribe messaging with fan-out delivery to individual subscribers and competing-consumer delivery via consumer groups.

- **TCP** — Custom binary protocol for persistent subscriptions with server-driven delivery
- **HTTP** — RESTful endpoints for fire-and-forget publish, query, and fetch operations

---

## Installation

### Pre-built binaries (recommended)

Statically linked binaries with no runtime dependencies:

```bash
curl -fsSL https://bitbucket.org/thermsio/fafb-q/downloads/install.sh | sh
```

Or manually:

```bash
# Linux x86_64
curl -LO https://bitbucket.org/thermsio/fafb-q/downloads/fafb-q-latest-x86_64-unknown-linux-musl.tar.gz
tar xzf fafb-q-latest-x86_64-unknown-linux-musl.tar.gz --strip-components=1
sudo cp fafb-q /usr/local/bin/

# Linux ARM64
curl -LO https://bitbucket.org/thermsio/fafb-q/downloads/fafb-q-latest-aarch64-unknown-linux-musl.tar.gz
tar xzf fafb-q-latest-aarch64-unknown-linux-musl.tar.gz --strip-components=1
sudo cp fafb-q /usr/local/bin/
```

Versioned downloads are also available at [Bitbucket Downloads](https://bitbucket.org/thermsio/fafb-q/downloads/).

### Live upgrade

Upgrade a running server with zero downtime:

```bash
FAFB_ADMIN_API_KEY=mykey curl -fsSL https://bitbucket.org/thermsio/fafb-q/downloads/rolling-upgrade.sh | sh
```

Or with a local copy:

```bash
FAFB_ADMIN_API_KEY=mykey ./scripts/rolling-upgrade.sh
```

See `scripts/rolling-upgrade.sh --help` for options (custom admin URL, pre-staged binary, force mode). Full deploy documentation: [`docs/deploy.md`](docs/deploy.md).

### From crates.io

Works on macOS (Apple Silicon & Intel), Linux, and anywhere Rust compiles:

```bash
cargo install fafb-q
```

### Build from source

```bash
cargo build --release
```

### Docker

```bash
docker compose -f docker-compose.test.yml up server
```

---

## Quick Start

```bash
cp config/config.example.toml config.toml
# Edit config.toml — at minimum, change the api_key values
fafb-q --config config.toml
```

The server starts a TCP listener on `127.0.0.1:9876` and an HTTP server on `127.0.0.1:8080` by default. See [`config/config.example.toml`](config/config.example.toml) for all options.

---

## Key Concepts

- **Namespaces** — top-level isolation unit with its own API key and permissions (`Subscribe`, `Publish`, `Query`, `Fetch`). One TCP connection = one namespace.
- **Topics** — named, append-only message logs within a namespace. Auto-created on first publish.
- **Fan-out** — every message delivered to all individual subscribers.
- **Consumer groups** — competing consumers share an offset; each message delivered to exactly one member.
- **Dead-letter queue** — messages exceeding max redelivery attempts are routed to `{topic}__dlq`.
- **Fetch** — stateless pull-based consumption (no subscriptions or server-side state).

---

## Building & Testing

Rust edition: **2024**

```bash
cargo build                    # debug build
cargo build --release          # release build
cargo test                     # run all tests
cargo test <test_name>         # run a single test
cargo clippy                   # lint
cargo fmt                      # format
cargo bench                    # benchmarks (criterion)
```

Docker-based testing with resource constraints: `./scripts/docker-test.sh --help`

Release builds: `./scripts/release.sh --help` — see [`docs/release-checklist.md`](docs/release-checklist.md)

---

## Documentation

| Document | Description |
|---|---|
| [`docs/protocol.md`](docs/protocol.md) | TCP wire format specification (authoritative) |
| [`docs/api.md`](docs/api.md) | HTTP API specification |
| [`docs/architecture.md`](docs/architecture.md) | System architecture, delivery mechanics, lifecycle |
| [`docs/design_decisions.md`](docs/design_decisions.md) | Cross-cutting design decision log |
| [`docs/deploy.md`](docs/deploy.md) | Graceful deployment and shutdown |
| [`docs/baselines.md`](docs/baselines.md) | Performance benchmark baselines |
| [`docs/release-checklist.md`](docs/release-checklist.md) | Release process |
| [`docs/client_sdk_spec.md`](docs/client_sdk_spec.md) | Client SDK implementation guide |
| [`docs/client_sdk_deploy.md`](docs/client_sdk_deploy.md) | Client SDK deploy/reconnection guide |
| [`docs/cli.md`](docs/cli.md) | CLI reference and subcommands |
| [`docs/server-tuning.md`](docs/server-tuning.md) | Server tuning for common deployment sizes |
| [`docs/wildcard_subscriptions.md`](docs/wildcard_subscriptions.md) | Wildcard subscription patterns |
| [`docs/delivery_guarantees.md`](docs/delivery_guarantees.md) | Delivery semantics and durability reference |
| [`docs/fetch_consumer_guide.md`](docs/fetch_consumer_guide.md) | Fetch consumer patterns and gotchas |
| [`config/config.example.toml`](config/config.example.toml) | Annotated example configuration |

---

## Contributing

```bash
cargo build                    # debug build
cargo test                     # run all tests
cargo clippy                   # lint
cargo fmt -- --check           # check formatting
```

Docker-based testing with resource constraints is available via `./scripts/docker-test.sh --help`.

Before submitting changes:

1. `cargo fmt` and `cargo clippy` must pass cleanly
2. All existing tests must pass (`cargo test`)
3. Add tests for new functionality — unit tests inline (`#[cfg(test)]`), integration tests in `tests/`
4. If your change affects the TCP protocol, HTTP API, or configuration, update the corresponding doc in `docs/` and `config/config.example.toml`

### Releasing

See [`docs/release-checklist.md`](docs/release-checklist.md) for the full process. The short version:

1. Update version in `Cargo.toml`, commit, and tag (`git tag v0.X.0`)
2. Push with tags — Bitbucket Pipeline builds Linux artifacts and publishes to crates.io

---

## License

See [LICENSE](LICENSE) for details.
