Skip to content

ARTEMIS-6358 Fix race when sending concurrent retained messages - #6879

Merged
jbertram merged 1 commit into
apache:mainfrom
grepjava:ARTEMIS-6358
Nov 9, 2026
Merged

jbertram merged 1 commit into
apache:mainfrom
grepjava:ARTEMIS-6358

Conversation

@grepjava

@grepjava grepjava commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

MQTTRetainMessageManager.handleRetainedMessage looked up the topic's retain queue and created it when missing with createQueue(QueueConfiguration). Two connections publishing the first retained messages to a topic at the same time could both find no queue, and the second createQueue threw ActiveMQQueueExistsException (AMQ229019). The publish was rolled back and the client got no PUBACK: the message reached neither the subscribers nor the retain queue.

The queue is now created with ignoreIfExists, so a connection that loses the race uses the queue the other one created.

MQTTTest.testFirstRetainedMessagesPublishedAtOnce has 16 clients publish a retained QoS 1 message to a new topic at once, for 10 topics, and checks that every publish is acknowledged and a new subscriber gets one retained message. It fails without the fix.

https://issues.apache.org/jira/browse/ARTEMIS-6358

@jbertram

jbertram commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

I'm confused by the title referencing lost messages. Typically a "lost" message is one where the client has every confidence that the message was actually published successfully when, in fact, it wasn't. If a publisher gets no PUBACK then it can assume the corresponding PUBLISH was not successful so there is no "lost" message.

It seems that a commit message like "fix race when sending concurrent retained messages" would be more accurate.

@grepjava

grepjava commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

You're right, "lost" isn't accurate here — the client never gets a PUBACK for the failed publish, so on QoS 1 it just retries and the retained message lands. The real defect is the race itself: two connections publishing a retained message to the same new topic at once both see locateQueue return null and both call createQueue, and the loser gets an exception. I've retitled the PR and the commit to "Fix race when sending concurrent retained messages" and reworded the commit body accordingly. Thanks for the catch.

@grepjava grepjava changed the title ARTEMIS-6358 Retained messages published at once to a new MQTT topic are not lost ARTEMIS-6358 Fix race when sending concurrent retained messages Nov 9, 2026
When two connections publish a retained message to the same new topic at
once, both see locateQueue return null and both call createQueue for the
retain queue; the loser gets an exception and its publish fails. Pass
ignoreIfExists=true so a connection that loses the race uses the queue the
winner created instead of failing.
@jbertram
jbertram merged commit a292ed3 into apache:main Nov 9, 2026
6 checks passed
@jbertram

jbertram commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Thanks, @grepjava!

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.

2 participants