Skip to content

WIP: [#1715] Jakarta Messaging 3.1 Shared Topic Support (Preview)#2225

Closed
mattrpav wants to merge 4 commits into
apache:mainfrom
mattrpav:amq-gh-1715-shared-topics
Closed

WIP: [#1715] Jakarta Messaging 3.1 Shared Topic Support (Preview)#2225
mattrpav wants to merge 4 commits into
apache:mainfrom
mattrpav:amq-gh-1715-shared-topics

Conversation

@mattrpav

@mattrpav mattrpav commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
  • Separate SharedTopicBrokerService allows for isolated testing
  • Separate SharedTopicConnectionFactory allows for isolated testing
  • OpenWire v13 w/ Shared Topic Subscription info and deliveryDelay accessors
  • Ability to migrate non-shared to shared (spec limitation work-around)

Jakarta Messaging specification calls out the Shared Topics are essentially a separate region from non-Shared topics. This works in our favor, as we can leverage *Region separation and implement this along side current topic support and not have to overhaul existing topic and subscription behavior.

Note: The SharedTopicBrokerService and SharedTopicConnectionFactory are intended to be transitional classes. This approach would allow us to release the feature as experimental/preview (if we chose) and keep the code path out of the stable current broker code. Once the implementation feels right, the last step would be to merge SharedTopicBrokerService -> BrokerService, etc.

mattrpav added 4 commits July 16, 2026 18:10
… advisory handling

- serviceRemoteConsumerAdvisory() used an exact class check
(data.getClass() == ConsumerInfo.class) which silently drops any
ConsumerInfo subclass. Change to instanceof so subclasses are
accepted by the advisory processing path.
- DemandForwardingBridgeSupport for subscriptions with same name
When multiple consumers share a durable subscription and ack
messages out of order, a blind overwrite of LastAck can move the
ack position backward. On restart, the recovery cursor replays
already-acked messages. Check the update with a forward-only check
so LastAck only advances.

Test demonstrates recovery cost when lastAckedSequence regresses due to
blind overwrite during out-of-order acks. Two durable subscriptions
share a topic; the fast subscription acks 499 of 500 messages in
reverse order. Without the forward-only guard in MessageDatabase,
lastAck regresses to sequence 1 and recovery scans all 499 entries.
…upport

Introduces protocol version 13, extending v12 with the fields needed to
carry JMS 3.1 shared subscription state across the wire and through
KahaDB recovery:

  ConsumerInfo      + shared, durable   (via SharedConsumerInfo)
  SubscriptionInfo  + shared            (via SharedSubscriptionInfo)
  ExceptionResponse + errorCode
  Message           + deliveryTime

The v13 MarshallerFactory clones the v12 marshaller map and replaces only
the ten marshallers affected. OpenWireFormat already resolves the factory
reflectively by version, so no version switch is required.

Because OpenWire marshals a throwable as type and message only, the
JMSException errorCode does not survive the round trip. The separate
errorCode field carries it, and ExceptionResponse.getException()
reapplies it to the reconstructed exception.

Nothing here activates at the default store version: v13 is selected only
when a broker sets storeOpenWireVersion to 13. Tests assert that gate
directly -- deliveryTime, errorCode and the shared flags all fail to
cross a v12 wire, and v12 continues to yield plain ConsumerInfo and
SubscriptionInfo instances.

ActiveMQErrorCode and SharedSubscriptionKey have no callers yet; they are
scaffolding for the shared subscription broker work that follows.

Adds 89 tests: round trips for all ten replaced marshallers in tight and
loose encodings, the errorCode reconstruction branches, and null-clientId
handling in SharedSubscriptionKey.
 - SharedTopicBrokerService (server-side entry point)
 - SharedTopicConnectionFactory (client-side entry point)
@cshannon

Copy link
Copy Markdown
Contributor

@mattrpav - Thanks for getting this started, I'll just make a couple points here.

This is going to be a lot of work so this isn't really suited for a single PR. The work here is going to need to be divided up and there will be some back and forth as we go. What I would recommend is the strategy we did in Apache Accumulo when we first started working on a major refactor of the project to make it more "elastic", and that is create a long running feature branch that we create PRs against.

One reason for the separate branch is we keep main clean until we are happy with the work. This is such a big feature that we might have to redo things and refactor a few times until we are happy with it. It's not possible to do it all in one big commit but it also doesn't make sense to merge work that is half done. During the initial work things are going to break, it's just a big refactor and that is fine becuase it will be isolated outside of main.

The other reason is we can avoid the extra work for the transition stuff. In fact, your PR directly illustrates this because you had to create classes like SharedTopicBrokerService which are throw away and I'd rather avoid. If we keep it separate we don't need to do that. We can just update BrokerService directly as there is no need to worry about isolated testing because the feature branch is doing the isolation for us.

After creating the branch we need to periodically merge the main branch into it (note I said merge, we don't want to rebase) to keep things up to date. Once we thing it's good we can create a PR and merge the feature branch back into main and preserve the commit history.

So the basic flow would be:

  1. Create a feature branch for shared sub support in the activemq repo
  2. periodically merge main into it to keep it up to date and resolve conflicts
  3. create PRs against the feature branch
  4. Merge the feature branch back into main when we are done

@cshannon

Copy link
Copy Markdown
Contributor

I moved the above comment into a dev list discussion here which is a better spot for it I think

@mattrpav

Copy link
Copy Markdown
Contributor Author

Replaced by [#2229] targeted to activemq-wip-jakarta-3.1 branch

@mattrpav mattrpav closed this Jul 18, 2026
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Apache ActiveMQ v6.4.0 Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants