Skip to content

drop stale deliveries routed to a discarded session - #180

Merged
fabracht merged 2 commits into
mainfrom
issue-150-clean-start-stray
Sep 28, 2026
Merged

fabracht merged 2 commits into
mainfrom
issue-150-clean-start-stray

Conversation

@fabracht

@fabracht fabracht commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #150

A publish routed to a client just before it reconnected with clean_start=1 could be pushed onto the session queue after the new session's bind() cleared it, delivering a message for a subscription the clean session never made.

Each ClientQueue now counts its full clears (epoch). A delivery plan records the epoch it was built under, and queue_behind pushes via push_in_epoch, which drops the message under the queue lock if the queue was fully cleared since. A resumed takeover never clears the queue, so its messages are kept. Partial clear(Some(cutoff)) does not advance the epoch.

File backend: a queued message's write was sent to the storage writer after the queue lock was released, so a concurrent clear or take could send its delete first. The late write then left the file on disk, and the message was redelivered after a restart. Writes are now sent while the lock is held, in append and requeue_front.

Tests:

  • clean_start_drops_a_publish_planned_for_the_previous_session (reproduced the bug before the fix)
  • resumed_session_keeps_a_publish_planned_for_the_previous_connection
  • push_in_epoch_refuses_a_message_routed_before_a_clear
  • writer_never_sees_a_write_after_the_delete_of_the_same_entry (before the fix, about 10k rewritten entries per run; after, 0)

mqtt5 0.43.1 (additive: ClientQueue::epoch, ClientQueue::push_in_epoch).

@fabracht
fabracht merged commit e13cc29 into main Sep 28, 2026
16 checks passed
@fabracht
fabracht deleted the issue-150-clean-start-stray branch September 28, 2026 01:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

QoS1 backlog: clean-start reconnect racing an in-flight publish can deliver one stray message

1 participant