Topic Manager Swiftlet
Overview
The Topic Manager Swiftlet manages the lifecycle and routing of topics in the SwiftMQ router. It handles topic creation and deletion, manages subscriptions (including durable and non-durable), and coordinates topic announcements and synchronization across routers in a network. The Swiftlet also implements flow control and slow subscriber detection for publish/subscribe messaging patterns.
Features
Topic Lifecycle Management
The Topic Manager Swiftlet allows for the creation and deletion of topics. Topics are defined hierarchically, and each root topic is managed by a dedicated virtual queue with the naming pattern tpc$<roottopic>. When a topic is created, it is registered with the JNDI Swiftlet (if present) for lookup. Deleting a topic removes it from the broker and deregisters it from JNDI. The Swiftlet ensures that topics are created as needed for both normal and durable subscriptions, and prevents duplicate topic definitions.
Topic Definition
Topics are defined under the topics entity list in the configuration. Each topic must have a valid hierarchical name. The Swiftlet verifies topic names for correctness and uniqueness.
JNDI Registration
If the JNDI Swiftlet is available, topics are registered as JNDI objects for external lookup and integration.
Configuration Example:
<swiftlet name="sys$topicmanager">
<topics>
<topic name="orders"/>
<topic name="news.europe"/>
</topics>
</swiftlet>
Subscription Management
The Swiftlet manages both non-durable and durable subscriptions to topics. Subscriptions can be created with optional message selectors and the noLocal flag, which prevents a subscriber from receiving messages it publishes itself. Durable subscriptions are persisted and survive client disconnects, while non-durable subscriptions are temporary and tied to the client session. Each subscription is associated with a queue for message delivery: durable subscriptions use a queue named <clientId>$<durableName>, while non-durable subscriptions use temporary queues. The Swiftlet ensures proper cleanup and removal of subscriptions and their associated queues.
Durable Subscription Naming
Durable subscriptions create a queue named <clientId>$<durableName>. This queue persists messages for the subscriber even when the client is offline.
Message Selectors and NoLocal
Subscriptions can specify a message selector (SQL-like predicate) to filter messages, and the noLocal flag to avoid receiving messages published by the same client.
Configuration Example:
<swiftlet name="sys$topicmanager">
<usage>
<durables>
<durables name="myclient$mydurable" clientid="myclient" durablename="mydurable" topic="orders" nolocal="true" selector="priority = 'high'"/>
</durables>
</usage>
</swiftlet>
Publish/Subscribe Flow Control
The Swiftlet implements flow control for publish/subscribe messaging to prevent message overload and ensure fair delivery to all subscribers. When enabled, flow control mechanisms monitor subscriber queues and can delay publishers if subscribers are slow to consume messages. This helps prevent memory exhaustion and message loss in high-throughput scenarios.
Configuration Example:
<swiftlet name="sys$topicmanager" flowcontrol-enabled="false"/>
Direct Subscriber Selection
With direct subscriber selection enabled, the Topic Manager matches published messages to subscribers based strictly on the topic name, rather than interpreting the publisher's topic as a SQL-like predicate. This provides predictable and efficient message routing for standard topic hierarchies. Disabling this feature allows for more flexible, predicate-based topic matching.
Configuration Example:
<swiftlet name="sys$topicmanager" direct-subscriber-selection="false"/>
Slow Subscriber Detection and Handling
The Swiftlet can detect slow subscribers based on configurable conditions for each root topic. If a subscriber's queue exceeds a threshold number of messages, and matches specified persistence and subscription type criteria, the Swiftlet can take action. For non-durable subscribers, it can disconnect the client. For durable subscribers, it can disconnect and delete the durable subscription and its queue. This helps maintain system health by preventing slow consumers from degrading overall performance.
Slow Subscriber Condition Parameters
Each condition is defined for a root topic and includes:
- max-messages: Maximum messages allowed in the subscriber queue before action is taken.
- persistence-mode: Which message types to consider (all, persistent, non_persistent).
- subscription-type: Which subscriber types to monitor (all, local, remote).
- disconnect-non-durable-subscriber: Whether to disconnect slow non-durable subscribers.
- disconnect-delete-durable-subscriber: Whether to disconnect and delete slow durable subscribers.
Configuration Example:
<swiftlet name="sys$topicmanager">
<slow-subscriber-conditions>
<topic name="orders" max-messages="1000" persistence-mode="all" subscription-type="local" disconnect-non-durable-subscriber="true" disconnect-delete-durable-subscriber="true"/>
</slow-subscriber-conditions>
</swiftlet>
Static Remote Router Subscriptions
The Swiftlet supports static subscriptions to topics on remote routers. This is configured by specifying remote routers and the root topics to subscribe to. Optionally, a static subscription can be kept even if the remote router unsubscribes. This feature is used for store-and-forward and network-wide topic propagation.
Keep on Unsubscribe
The keep-on-unsubscribe flag ensures that the static subscription remains active even if the remote router unsubscribes from the topic.
Configuration Example:
<swiftlet name="sys$topicmanager">
<static-remote-router-subscriptions>
<static-remote-router-subscription name="router2">
<static-topic-subscriptions>
<static-topic-subscription name="orders" keep-on-unsubscribe="true"/>
</static-topic-subscriptions>
</static-remote-router-subscription>
</static-remote-router-subscriptions>
</swiftlet>
Topic Announcement and Synchronization
The Swiftlet automatically announces topic creation, removal, and subscription changes to other routers in the network. This is achieved via the sys$topic queue and a dedicated announce receiver and sender. Announce filters can be configured to control which topics and routers receive announcements, using SQL-LIKE predicates for router and topic names. This ensures efficient and controlled propagation of topic information across a SwiftMQ network.
Announce Filters
Announce filters allow inclusion or exclusion of specific routers and topics from receiving topic announcements. Filters are defined using SQL-LIKE predicates.
Configuration Example:
<swiftlet name="sys$topicmanager">
<announce-filters>
<router-name-filter name="router2" routername="router2" filter-type="exclude">
<topic-filters>
<topic-name-filter name="internal.%"/>
</topic-filters>
</router-name-filter>
</announce-filters>
</swiftlet>
Internal Queue Naming
tpc$<roottopic>— Virtual queue for topic broker invocation<clientId>$<durableName>— Queue for durable topic subscriptionsys$topic— Queue for topic announcement and synchronization between routers
Configuration Guide
Enabling Flow Control for Publish/Subscribe
Enable flow control to prevent publishers from overwhelming slow subscribers, ensuring reliable delivery and system stability.
- Set the
flowcontrol-enabledattribute totrueon thesys$topicmanagerswiftlet. - Restart the router for the change to take effect.
<swiftlet name="sys$topicmanager" flowcontrol-enabled="true"/>
Defining a Slow Subscriber Condition for a Topic
Automatically disconnect and delete slow durable subscribers on the orders topic if their queue exceeds 1000 messages.
- Add a
topicentry underslow-subscriber-conditionsfor theordersroot topic. - Set
max-messagesto1000. - Set
disconnect-delete-durable-subscribertotrue.
<swiftlet name="sys$topicmanager">
<slow-subscriber-conditions>
<topic name="orders" max-messages="1000" disconnect-delete-durable-subscriber="true"/>
</slow-subscriber-conditions>
</swiftlet>
Creating a Durable Subscription
Create a durable subscription for client myclient with durable name mydurable on topic orders.
- Add an entry under
usage/durableswith the appropriateclientid,durablename, andtopic. - Optionally specify
nolocalandselectorattributes.
<swiftlet name="sys$topicmanager">
<usage>
<durables>
<durables name="myclient$mydurable" clientid="myclient" durablename="mydurable" topic="orders"/>
</durables>
</usage>
</swiftlet>
Filtering Topic Announcements to a Router
Exclude all topic announcements to router router2 except those matching public.%.
- Add a
router-name-filterunderannounce-filtersforrouter2. - Set
filter-typetoinclude. - Add a
topic-name-filterwith namepublic.%.
<swiftlet name="sys$topicmanager">
<announce-filters>
<router-name-filter name="router2" routername="router2" filter-type="include">
<topic-filters>
<topic-name-filter name="public.%"/>
</topic-filters>
</router-name-filter>
</announce-filters>
</swiftlet>
Scheduler Jobs
Delete Durable
Description: Delete durable Subscribers
Configuration Reference
The top-level entity in routerconfig.xml is <swiftlet name="sys$topicmanager">.
<swiftlet name="sys$topicmanager"> Properties
These properties are attributes of the <swiftlet name="sys$topicmanager"> entity.
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
flowcontrol-enabled |
Boolean | true |
No | No | Enable/Disable Publish/Subscribe Flow Control |
direct-subscriber-selection |
Boolean | true |
No | No | Select Subscribers directly and do NOT interpret the Publisher's Topic Name as SQL-Like Predicate |
<swiftlet name="sys$topicmanager" flowcontrol-enabled="true" direct-subscriber-selection="true"/>
<topics> in <swiftlet name="sys$topicmanager">
Topic Definitions
Each <topic> entry is identified by its name attribute (the Topic).
<swiftlet name="sys$topicmanager">
<topics>
<topic name="..."/>
</topics>
</swiftlet>
<announce-filters> in <swiftlet name="sys$topicmanager">
Topic Announce Filters
Each <router-name-filter> entry is identified by its name attribute (the Router Name Filter).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
routername |
String | — | Yes | No | SQL LIKE Predicate to match router names |
filter-type |
String | exclude |
No | No | Filter Type (choices: include, exclude) |
<swiftlet name="sys$topicmanager">
<announce-filters>
<router-name-filter name="..." routername="..."/>
</announce-filters>
</swiftlet>
<topic-filters> in <announce-filters>
Topic Filters
Each <topic-name-filter> entry is identified by its name attribute (the Topic Name Filter).
<swiftlet name="sys$topicmanager">
<announce-filters>
<router-name-filter name="...">
<topic-filters>
<topic-name-filter name="..."/>
</topic-filters>
</router-name-filter>
</announce-filters>
</swiftlet>
<slow-subscriber-conditions> in <swiftlet name="sys$topicmanager">
Slow Subscriber Conditions
Each <topic> entry is identified by its name attribute (the Root Topic).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
max-messages |
Long | 500 |
Yes | No | Maximum Messages in Subscriber Queue (min: 1) |
persistence-mode |
String | non_persistent |
No | No | Persistence Mode (choices: all, non_persistent, persistent) |
subscription-type |
String | all |
No | No | Subscription Type (choices: all, local, remote) |
disconnect-non-durable-subscriber |
Boolean | false |
No | No | Disconnect Non-Durable Subscriber |
disconnect-delete-durable-subscriber |
Boolean | false |
No | No | Disconnect and Delete Durable Subscriber |
<swiftlet name="sys$topicmanager">
<slow-subscriber-conditions>
<topic name="..." max-messages="..."/>
</slow-subscriber-conditions>
</swiftlet>
<static-remote-router-subscriptions> in <swiftlet name="sys$topicmanager">
Static Remote Router Subscriptions
Each <static-remote-router-subscription> entry is identified by its name attribute (the Static Remote Router Subscription).
<swiftlet name="sys$topicmanager">
<static-remote-router-subscriptions>
<static-remote-router-subscription name="..."/>
</static-remote-router-subscriptions>
</swiftlet>
<static-topic-subscriptions> in <static-remote-router-subscriptions>
Static Topic Subscriptions
Each <static-topic-subscription> entry is identified by its name attribute (the Static Topic Subscription).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
keep-on-unsubscribe |
Boolean | false |
No | No | Keep this Subscription even when the remote Router unsubscribes it |
<swiftlet name="sys$topicmanager">
<static-remote-router-subscriptions>
<static-remote-router-subscription name="...">
<static-topic-subscriptions>
<static-topic-subscription name="..."/>
</static-topic-subscriptions>
</static-remote-router-subscription>
</static-remote-router-subscriptions>
</swiftlet>