Follow-ups from the publish-outcome work in #164 (PublishResult::Queued, PublishHandle, TLA+ model in specs/tla/offline-queue/). None of these is a conformance violation.
- Offline queue has no configurable bound. It is limited only by the packet-id space (65535 queued QoS 1/2 messages), and every entry holds its full payload, so memory is effectively unbounded for large payloads. Add a configurable limit (count and/or bytes) with a documented overflow policy. Rejecting at
publish() with a clear error fits the outcome model better than dropping silently.
- QoS 2 packet-id quarantine is not persisted. An abandoned QoS 2 id is quarantined in memory until a Session Present=0 connection. After a process restart that resumes the broker session with
resume_existing_session, the quarantine is gone, and a new QoS 2 publish can reuse an id the broker still holds (it would be treated as a duplicate). Persist it with the session state, or document the limitation.
- Offline-queued publishes skip the codec registry and OpenTelemetry trace injection. The live path applies both; the queued path builds the packet without them.
- Cancelling a live
publish() future leaks a quota slot. If the future is dropped after it claimed send quota but before the message was stored, one Receive Maximum slot stays taken until the next reconnect.
Follow-ups from the publish-outcome work in #164 (
PublishResult::Queued,PublishHandle, TLA+ model inspecs/tla/offline-queue/). None of these is a conformance violation.publish()with a clear error fits the outcome model better than dropping silently.resume_existing_session, the quarantine is gone, and a new QoS 2 publish can reuse an id the broker still holds (it would be treated as a duplicate). Persist it with the session state, or document the limitation.publish()future leaks a quota slot. If the future is dropped after it claimed send quota but before the message was stored, one Receive Maximum slot stays taken until the next reconnect.