Topic Manager Swiftlet
Overview
The Topic Manager Swiftlet manages the lifecycle, routing, and subscription handling for all topics in a SwiftMQ router. It provides dynamic topic creation and deletion, manages durable and non-durable subscriptions, handles topic announcements for clustering, and enforces slow subscriber policies. The Swiftlet ensures that publish/subscribe semantics are maintained across local and clustered routers, including propagation of topic and subscription information.
Features
Dynamic Topic Management
The Topic Manager Swiftlet allows for the dynamic creation and deletion of topics. Topics are defined under the topics entity list, and can be created or removed at runtime. When a topic is created, it is registered with JNDI (if enabled) and a corresponding virtual queue (tpc$<roottopic>) is created to manage message flow for that topic hierarchy. Topic creation and removal events are broadcast to other routers in a cluster to maintain consistent topic state.
Topic Hierarchies
Topics can be organized hierarchically using the dot (.) delimiter. The root segment of the topic name determines the virtual queue (tpc$<roottopic>) used for message processing.
Configuration Example:
<swiftlet name="sys$topicmanager">
<topics>
<topic name="orders"/>
<topic name="news.sports"/>
</topics>
</swiftlet>
Subscription Handling
The Swiftlet manages both durable and non-durable subscriptions to topics. Non-durable subscriptions are associated with temporary queues, while durable subscriptions are associated with persistent queues named according to the pattern <clientId>$<durableName>. Subscriptions can specify a message selector (SQL-like predicate with % as wildcard) and a noLocal flag to filter out messages published by the same client. Subscriptions are tracked and managed for both local and remote (clustered) routers, with remote subscriptions being propagated via topic announcements.
Durable Subscription Queue Naming
Durable subscriptions are bound to queues named <clientId>$<durableName>. The clientId is stripped of any @routername suffix for queue naming purposes.
Subscription Properties
Each subscription can specify a selector (for message filtering) and a nolocal flag (to prevent receiving messages published by the same client). These are set as attributes on the subscription entity.
Configuration Example:
<swiftlet name="sys$topicmanager">
<usage>
<durables>
<durables name="myclient$mydurable" clientid="myclient" durablename="mydurable" topic="orders" nolocal="true" selector="priority > 5"/>
</durables>
</usage>
</swiftlet>
Publish/Subscribe Flow Control
Flow control can be enabled or disabled for publish/subscribe operations. When enabled, the Swiftlet applies backpressure to publishers if subscriber queues are full, ensuring reliable delivery and preventing resource exhaustion. This is controlled via the flowcontrol-enabled property on the Swiftlet.
Configuration Example:
<swiftlet name="sys$topicmanager" flowcontrol-enabled="false"/>
Direct Subscriber Selection
The Swiftlet supports two modes for matching published messages to subscribers: direct subscriber selection and predicate-based selection. When direct-subscriber-selection is enabled (default), the publisher's topic name is matched directly to subscriber topic names. If disabled, the publisher's topic name is interpreted as a SQL-like predicate, and all matching subscribers receive the message. This provides flexibility for advanced publish/subscribe scenarios.
Configuration Example:
<swiftlet name="sys$topicmanager" direct-subscriber-selection="false"/>
Clustered Topic Announcements and Remote Subscriptions
In a clustered environment, the Topic Manager Swiftlet propagates topic and subscription information to other routers using topic announcements. This ensures that all routers are aware of available topics and active subscriptions, enabling seamless message routing across the cluster. Announce filters can be configured to control which topics and routers receive announcements, using SQL-like predicates for router and topic names.
Announce Filters
Announce filters are defined under the announce-filters entity list. Each filter specifies a routername predicate and a filter-type (include or exclude). Nested topic-filters allow fine-grained control over which topics are announced to which routers.
Configuration Example:
<swiftlet name="sys$topicmanager">
<announce-filters>
<router-name-filter name="router2" routername="router2" filter-type="include">
<topic-filters>
<topic-name-filter name="orders"/>
</topic-filters>
</router-name-filter>
</announce-filters>
</swiftlet>
Slow Subscriber Detection and Handling
The Swiftlet can detect slow subscribers based on configurable conditions and take automated actions. For each root topic, a slow subscriber condition can be defined specifying the maximum number of messages allowed in a subscriber's queue, the persistence mode (all, persistent, or non_persistent), and the subscription type (all, local, or remote). If a subscriber exceeds the threshold, the Swiftlet can disconnect non-durable subscribers and/or disconnect and delete durable subscribers, depending on the configuration.
Slow Subscriber Actions
The disconnect-non-durable-subscriber and disconnect-delete-durable-subscriber flags control whether non-durable and durable subscribers are disconnected and/or deleted when they become slow.
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 the configuration of static subscriptions to topics on remote routers. This is useful for ensuring that certain topics are always subscribed to across the cluster, regardless of dynamic subscription activity. Each static remote router subscription specifies a router name and a list of root topics to subscribe to. The keep-on-unsubscribe flag can be set to keep the subscription active even if the remote router unsubscribes.
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>
Internal Queue Naming
tpc$<roottopic>— Virtual queue for topic broker invocation; one per root topic segment. All messages for a topic hierarchy are processed via this queue.<clientId>$<durableName>— Queue for a durable topic subscription, used to persistently store messages for the subscriber.
Configuration Guide
Enabling Flow Control for Publish/Subscribe
Enable or disable flow control to manage backpressure on publishers when subscriber queues are full. Disabling flow control may improve throughput but risks message loss if queues overflow.
- Edit the routerconfig.xml file.
- Set the flowcontrol-enabled attribute on the sys$topicmanager swiftlet to true or false as needed.
- Restart the router for changes to take effect.
<swiftlet name="sys$topicmanager" flowcontrol-enabled="true"/>
Defining a Slow Subscriber Policy for a Topic
Automatically disconnect or delete slow subscribers on a specific root topic when their queue exceeds a threshold.
- Edit the routerconfig.xml file.
- Add a topic entry under slow-subscriber-conditions for the desired root topic.
- Set max-messages, persistence-mode, subscription-type, and desired disconnect flags.
- Restart the router for changes to take effect.
<swiftlet name="sys$topicmanager">
<slow-subscriber-conditions>
<topic name="alerts" max-messages="2000" disconnect-non-durable-subscriber="true"/>
</slow-subscriber-conditions>
</swiftlet>
Configuring Announce Filters to Limit Topic Propagation
Restrict which topics are announced to specific routers in a cluster to control subscription visibility and reduce network traffic.
- Edit the routerconfig.xml file.
- Add a router-name-filter entry under announce-filters with the desired routername and filter-type.
- Add topic-name-filter entries for each topic to include or exclude.
- Restart the router for changes to take effect.
<swiftlet name="sys$topicmanager">
<announce-filters>
<router-name-filter name="router3" routername="router3" filter-type="include">
<topic-filters>
<topic-name-filter name="news"/>
</topic-filters>
</router-name-filter>
</announce-filters>
</swiftlet>
Creating a Durable Subscription
Manually define a durable subscription for a client and topic, including message selector and noLocal flag.
- Edit the routerconfig.xml file.
- Add a durables entry under usage/durables with the appropriate clientid, durablename, topic, and optional selector/nolocal attributes.
- Restart the router for changes to take effect.
<swiftlet name="sys$topicmanager">
<usage>
<durables>
<durables name="alice$alerts" clientid="alice" durablename="alerts" topic="alerts" selector="priority > 5" nolocal="true"/>
</durables>
</usage>
</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>