diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 54f20f23..04f46de4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 - name: Cache dependencies uses: Swatinem/rust-cache@v2 @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 with: targets: ${{ matrix.target }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 81028d53..53480087 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 with: components: rustfmt - name: Check formatting (workspace) @@ -38,7 +38,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 with: components: clippy - name: Cache dependencies @@ -52,7 +52,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 - name: Cache dependencies uses: Swatinem/rust-cache@v2 - name: Run tests @@ -64,7 +64,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 - name: Cache dependencies uses: Swatinem/rust-cache@v2 - name: Build documentation @@ -78,7 +78,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@1.98.0 with: targets: wasm32-unknown-unknown - name: Cache dependencies diff --git a/CHANGELOG.md b/CHANGELOG.md index a07b91c8..d06efccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. Each entry lists the date and the crate versions that were released. +## 2026-09-07 — mqdb-agent 0.8.27, mqdb-cluster 0.4.13, mqdb-vault 0.1.5, mqdb-cli 0.8.36 + +### Changed + +- **Upgraded `mqtt5` from a git dependency (`0.35.1`) to the published crate `0.39.2`** (pulling `mqtt5-protocol 0.15.0`), and removed the `[patch.crates-io]` git override so all builds resolve mqtt5 from crates.io. The upgrade is API-compatible for everything MQDB uses (client, broker config/auth/events/bridge/acl, message types) — no source changes were needed. `mqtt5 0.39` adds `user_id` to the broker's client connect/disconnect events, which the upcoming presence feed depends on. +- **Pinned the Rust toolchain to 1.98.0** via `rust-toolchain.toml`, matching the mqtt5 library, and changed CI from `dtolnay/rust-toolchain@stable` to `@1.98.0` so local, CI, and the upstream library build on the same compiler. This removes the local-vs-CI clippy skew that previously let a lint pass locally and fail in CI. + ## 2026-09-05 — mqdb-core 0.7.12, mqdb-agent 0.8.26, mqdb-cluster 0.4.12, mqdb-vault 0.1.4, mqdb-wasm 0.3.6 ### Added diff --git a/Cargo.lock b/Cargo.lock index 044eca36..2d9149f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1420,7 +1420,7 @@ dependencies = [ [[package]] name = "mqdb-agent" -version = "0.8.26" +version = "0.8.27" dependencies = [ "arc-swap", "argon2", @@ -1455,7 +1455,7 @@ dependencies = [ [[package]] name = "mqdb-cli" -version = "0.8.35" +version = "0.8.36" dependencies = [ "base64", "bebytes", @@ -1482,7 +1482,7 @@ dependencies = [ [[package]] name = "mqdb-cluster" -version = "0.4.12" +version = "0.4.13" dependencies = [ "arc-swap", "bebytes", @@ -1537,7 +1537,7 @@ dependencies = [ [[package]] name = "mqdb-vault" -version = "0.1.4" +version = "0.1.5" dependencies = [ "base64", "mqdb-agent", @@ -1555,8 +1555,9 @@ dependencies = [ [[package]] name = "mqtt5" -version = "0.35.1" -source = "git+https://github.com/LabOverWire/mqtt-lib.git#563cc1ce26383b5f89cc289df476aa79aad8da99" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d9de73200ed2112ed25ebcdd5e74b22aa5c89065fd3554e111e3353e9d5f0" dependencies = [ "argon2", "base64", @@ -1602,8 +1603,9 @@ dependencies = [ [[package]] name = "mqtt5-protocol" -version = "0.14.1" -source = "git+https://github.com/LabOverWire/mqtt-lib.git#563cc1ce26383b5f89cc289df476aa79aad8da99" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d117c9886f0dfe05735a1c24eb7e6e51cf0a915312350477a2fa6e70392de1" dependencies = [ "bebytes", "bytes", @@ -2621,7 +2623,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", diff --git a/Cargo.toml b/Cargo.toml index 61a5d56a..af3644df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ zeroize = "1.8.2" clap = { version = "4.5", features = ["derive", "env"] } comfy-table = "7.2" fjall = "3.0" -mqtt5 = "0.35" +mqtt5 = "0.39" tokio = { version = "1.49", features = ["full"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } lru = "0.16" @@ -78,7 +78,3 @@ lto = true codegen-units = 1 panic = "abort" opt-level = "z" - -[patch.crates-io] -mqtt5 = { git = "https://github.com/LabOverWire/mqtt-lib.git" } -mqtt5-protocol = { git = "https://github.com/LabOverWire/mqtt-lib.git" } diff --git a/crates/mqdb-agent/Cargo.toml b/crates/mqdb-agent/Cargo.toml index e920097b..0e1cf0d7 100644 --- a/crates/mqdb-agent/Cargo.toml +++ b/crates/mqdb-agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mqdb-agent" -version = "0.8.26" +version = "0.8.27" edition.workspace = true license = "Apache-2.0" authors.workspace = true diff --git a/crates/mqdb-cli/Cargo.toml b/crates/mqdb-cli/Cargo.toml index d26d62f7..28618466 100644 --- a/crates/mqdb-cli/Cargo.toml +++ b/crates/mqdb-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mqdb-cli" -version = "0.8.35" +version = "0.8.36" publish = false edition.workspace = true license = "AGPL-3.0-only" diff --git a/crates/mqdb-cluster/Cargo.toml b/crates/mqdb-cluster/Cargo.toml index 0e81dcfe..0b559971 100644 --- a/crates/mqdb-cluster/Cargo.toml +++ b/crates/mqdb-cluster/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mqdb-cluster" -version = "0.4.12" +version = "0.4.13" publish = false edition.workspace = true license = "AGPL-3.0-only" diff --git a/crates/mqdb-vault/Cargo.toml b/crates/mqdb-vault/Cargo.toml index 2c4cc760..89527ef8 100644 --- a/crates/mqdb-vault/Cargo.toml +++ b/crates/mqdb-vault/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mqdb-vault" -version = "0.1.4" +version = "0.1.5" publish = false edition.workspace = true license = "AGPL-3.0-only" diff --git a/deny.toml b/deny.toml index e017fdc9..2d600377 100644 --- a/deny.toml +++ b/deny.toml @@ -39,4 +39,3 @@ wildcards = "allow" [sources] unknown-registry = "warn" unknown-git = "allow" -allow-git = ["https://github.com/LabOverWire/mqtt-lib"] diff --git a/docs/design/hold-reclaim.md b/docs/design/hold-reclaim.md index 4643d378..3cc98c83 100644 --- a/docs/design/hold-reclaim.md +++ b/docs/design/hold-reclaim.md @@ -154,15 +154,14 @@ larger change than the agent's batch tweak. 1. **Per-connection vs per-user binding.** Per-connection false-reclaims a user who still has another live connection. **Rec: per-user** (`_bound_user_id` + user-level presence aggregation). -2. **mqtt-lib `user_id`.** ✅ RESOLVED — shipped in mqtt5 `0.38.4` (pin `mqtt5 = "0.38.4"`, - replacing the git dep). Both `ClientConnectEvent` and `ClientDisconnectEvent` now carry +2. **mqtt-lib `user_id`.** ✅ RESOLVED & LANDED — the workspace is pinned to the published + `mqtt5 = "0.39"` (`0.39.2`), replacing the git dependency (done in its own step, ahead of + PR 3). Both `ClientConnectEvent` and `ClientDisconnectEvent` carry `pub user_id: Option>` (mirrors `ClientPublishEvent::user_id`; the authenticated username, `None` for anonymous). Read as `event.user_id.as_deref()`. `ClientDisconnectEvent` also has `client_id: Arc` + `unexpected: bool`, so the presence payload `{client_id, user_id, event, unexpected, ts}` is fully available (generate `ts`). This - unblocks the per-user binding in decision 1. The pin is a workspace dependency bump done - as its own step (it swaps a git dep for the published crate and needs its own build/test - verification), landing with or before PR 3. + unblocks the per-user binding in decision 1. 3. **Crash-detection latency.** Sub-second reclaim holds only for **graceful** disconnects; a hard crash is detected at the MQTT keepalive timeout. **Rec: short keepalive on hold connections + document** the crash-path bound. diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..41575b55 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.98.0" +components = ["clippy", "rustfmt"] +targets = ["wasm32-unknown-unknown"]