Pubsub Model
The design of the PubSub support in GLIDE aims to unify various nuances into a coherent interface, minimizing differences between Sharded, Cluster, and Standalone configurations. GLIDE is also responsible for tracking topology changes in real time, ensuring the client remains subscribed regardless of any connectivity issues.
Conceptually, the PubSub functionality can be divided into four actions: Subscribing, Publishing, Receiving, and Unsubscribing.
GLIDE supports two subscription models:
- Static (config-based): Subscriptions defined at client creation time as part of the initial configuration.
- Dynamic (GLIDE 2.3+): Subscriptions added or removed at runtime via explicit API calls.
Both models can coexist on the same client — you can define initial subscriptions in the config and later add or remove subscriptions dynamically. In both cases, GLIDE automatically restores subscription state after topology changes or server disconnects via the PubSub Synchronizer.
PubSub Synchronizer
Section titled “PubSub Synchronizer”At the heart of GLIDE’s PubSub implementation is the PubSub Synchronizer, a background component that manages the lifecycle of all subscriptions — both static and dynamic.
The synchronizer maintains two separate views of subscription state:
- Desired state: What the user wants to be subscribed to. Modified by API calls (
subscribe,unsubscribe, etc.) and by the initial config. - Actual state: What the server has confirmed via push notifications. Tracked per server address for cluster topology awareness.
A background reconciliation task runs continuously, waking either on an explicit trigger (e.g., a new subscribe/unsubscribe call, a topology change, or a disconnection) or on a periodic interval (default: every 3 seconds). Incoming push notifications from the server continuously update the actual subscription state, and the next reconciliation cycle picks up any discrepancies. Each reconciliation cycle:
- Computes the diff between desired and actual state
- Sends
SUBSCRIBEcommands for channels in desired but not in actual - Sends
UNSUBSCRIBEcommands for channels in actual but not in desired - Processes any pending unsubscribes caused by topology changes (slot migrations, node removals)
This architecture provides several benefits:
- Cluster-aware resubscription: If a connection drops, a node fails, or slots migrate, the synchronizer detects the discrepancy and automatically resubscribes on the correct nodes. Subscriptions are tracked per node address, so recovery is targeted rather than global.
- Subscription load balancing: In cluster mode, subscriptions are distributed across nodes using sharded semantics — each subscription is routed to the node that owns its slot. This spreads the PubSub load across the cluster rather than concentrating it on a single node.
- Consistent model: Both static and dynamic subscriptions flow through the same reconciliation logic, so they benefit equally from automatic recovery.
You can inspect the synchronizer’s state at any time using get_subscriptions(), which returns both the desired and actual subscription maps.
Subscribing
Section titled “Subscribing”All subscriptions — both static and dynamic — are routed to servers using the following logic:
- Standalone mode: Subscribe commands are applied to a random node, either a primary or one of the replicas.
- Cluster mode: For both Sharded and Non-sharded subscriptions, the Sharded semantics are used; the subscription is applied to the node holding the slot for the subscription’s channel/pattern. This ensures load distribution across all nodes in the cluster.
Static Subscriptions (Config-Based)
Section titled “Static Subscriptions (Config-Based)”Static subscriptions are defined during client creation as part of the client configuration.
Dynamic Subscriptions (GLIDE 2.3+)
Section titled “Dynamic Subscriptions (GLIDE 2.3+)”Dynamic subscriptions allow you to subscribe and unsubscribe at runtime without creating a new client. They come in two variants:
- Blocking (with timeout): Waits for server confirmation before returning. Accepts a
timeout_msparameter (0 = wait indefinitely). - Non-blocking (lazy): Updates the client’s desired subscription state and returns immediately. The actual subscription happens asynchronously in the background via the synchronizer’s reconciliation process.
| Operation | Blocking | Non-blocking (Lazy) |
|---|---|---|
| Subscribe to exact channels | subscribe(channels, timeout_ms) | subscribe_lazy(channels) |
| Subscribe to patterns | psubscribe(patterns, timeout_ms) | psubscribe_lazy(patterns) |
| Subscribe to sharded channels (cluster only) | ssubscribe(channels, timeout_ms) | ssubscribe_lazy(channels) |
| Unsubscribe from exact channels | unsubscribe(channels, timeout_ms) | unsubscribe_lazy(channels) |
| Unsubscribe from patterns | punsubscribe(patterns, timeout_ms) | punsubscribe_lazy(patterns) |
| Unsubscribe from sharded channels (cluster only) | sunsubscribe(channels, timeout_ms) | sunsubscribe_lazy(channels) |
NOTE: Method naming varies by language (e.g., subscribeLazy in Java/Node.js/Go, subscribe_lazy in Python). To unsubscribe from all channels/patterns, pass None/null/empty or use the constants ALL_CHANNELS, ALL_PATTERNS, ALL_SHARDED_CHANNELS.
Dynamic subscriptions work with both static and dynamic subscriptions — you can use unsubscribe to remove a channel that was originally defined in the static config.
Publishing
Section titled “Publishing”Publishing functionality is unified into a single command method with an optional/default parameter for Sharded mode (applicable only for Cluster mode clients). The routing logic for this command is as follows:
- Standalone mode: The command is routed to a primary node or a replica if
read-onlymode is configured. - Cluster mode: The command is routed to the server holding the slot for the command’s channel.
Receiving
Section titled “Receiving”There are three methods for receiving messages:
- Polling: A non-blocking method, typically named
tryGetMessage. It returns the next available message or nothing if no messages are available. - Async: An asynchronous method, returning a CompletableFuture, typically named
getMessage. - Callback: A user-provided callback function that receives the incoming message along with the user-provided context. Note that the callback code must be thread-safe for applicable languages.
The intended method is selected during client creation with the subscription configuration. When the configuration includes a callback (and an optional context), incoming messages will be passed to that callback as they arrive. Calls to the polling/async methods are prohibited and will fail. In the case of async/polling, incoming messages will be buffered in an unbounded buffer. The user should ensure timely extraction of incoming messages to avoid straining the memory subsystem.
Messages have three kinds based on how they were subscribed:
- Message — from exact channel subscriptions (
SUBSCRIBE) - PMessage — from pattern subscriptions (
PSUBSCRIBE) - SMessage — from sharded channel subscriptions (
SSUBSCRIBE, cluster only)
Unsubscribing
Section titled “Unsubscribing”Prior to GLIDE 2.3: The subscription configuration is immutable and applied upon client creation, so no methods for runtime unsubscribing are provided. Additionally, issuing commands such as UNSUBSCRIBE/PUNSUBSCRIBE/SUNSUBSCRIBE via the custom commands interface may lead to unpredictable behavior. Subscriptions are removed from servers upon client closure, typically as a result of the client’s object destructor. Note that some languages, such as Python, might require an explicit call to a cleanup method, e.g.:
client.close()GLIDE 2.3+: Use the unsubscribe / punsubscribe / sunsubscribe methods (blocking or lazy variants) described in the Dynamic Subscriptions section above. To unsubscribe from all channels/patterns of a given type, pass None/null/empty, or use the provided constants (ALL_CHANNELS, ALL_PATTERNS, ALL_SHARDED_CHANNELS). This works for both statically and dynamically subscribed channels. Remaining subscriptions are still cleaned up on client closure.
Unsubscribe commands are routed as follows:
- Standalone mode: Unsubscribe commands (
UNSUBSCRIBE,PUNSUBSCRIBE) are sent to all nodes. This is necessary because in environments like ElastiCache, the DNS address may change, making it impossible to know which specific node holds the subscription. - Cluster mode: Unsubscribe commands are routed to the specific node address where the subscription is tracked. For sharded unsubscribes (
SUNSUBSCRIBE), channels are grouped by slot and each group is sent to the appropriate slot owner.
Subscription State Introspection (GLIDE 2.3+)
Section titled “Subscription State Introspection (GLIDE 2.3+)”Use get_subscriptions() to inspect the current subscription state. It returns both the desired subscriptions (what you’ve requested) and the actual subscriptions (what the server has confirmed). This is useful for verifying that dynamic subscriptions have been fully applied, especially when using non-blocking (lazy) operations.
What’s Next
Section titled “What’s Next”Take a look at our Pub/Sub Messaging how-to for usage examples across all supported languages.