Pure functions for pub/sub topic management.
Implements topic-based message routing where connections can subscribe to topics and receive messages published to those topics. All functions are pure (no I/O, no side effects) following FC/IS pattern.
Key Features:
Data Structure: Subscriptions are represented as a map: {topic-name #{connection-id-1 connection-id-2 ...}}
Pure functions for pub/sub topic management.
Implements topic-based message routing where connections can subscribe to
topics and receive messages published to those topics. All functions are pure
(no I/O, no side effects) following FC/IS pattern.
Key Features:
- Subscribe connection to topic (add to subscription set)
- Unsubscribe connection from topic (remove from set)
- Find all subscribers for topic (set intersection)
- Clean up subscriptions on disconnect (remove all for connection)
Data Structure:
Subscriptions are represented as a map:
{topic-name #{connection-id-1 connection-id-2 ...}}(create-subscription connection-id topic now)Create new subscription record (pure).
Args: connection-id - UUID of WebSocket connection topic - Topic name string (e.g. 'order:123', 'user:456:messages')
Returns: Subscription map with :connection-id, :topic, :created-at
Example: (create-subscription #uuid "123..." "order:456") => {:connection-id #uuid "123..." :topic "order:456" :created-at #inst "2025-01-01T12:00:00Z"}
Create new subscription record (pure).
Args:
connection-id - UUID of WebSocket connection
topic - Topic name string (e.g. 'order:123', 'user:456:messages')
Returns:
Subscription map with :connection-id, :topic, :created-at
Example:
(create-subscription #uuid "123..." "order:456")
=> {:connection-id #uuid "123..."
:topic "order:456"
:created-at #inst "2025-01-01T12:00:00Z"}(get-connection-topics subscriptions connection-id)Get all topics connection is subscribed to (pure).
Args: subscriptions - Current subscriptions map connection-id - UUID of connection
Returns: Set of topic name strings connection is subscribed to
Example: (get-connection-topics {"order:456" #{#uuid "111..."} "user:789" #{#uuid "111..." #uuid "222..."}} #uuid "111...") => #{"order:456" "user:789"}
Get all topics connection is subscribed to (pure).
Args:
subscriptions - Current subscriptions map
connection-id - UUID of connection
Returns:
Set of topic name strings connection is subscribed to
Example:
(get-connection-topics {"order:456" #{#uuid "111..."}
"user:789" #{#uuid "111..." #uuid "222..."}}
#uuid "111...")
=> #{"order:456" "user:789"}(get-subscribers subscriptions topic)Get all connection IDs subscribed to topic (pure).
Args: subscriptions - Current subscriptions map topic - Topic name string
Returns: Set of connection UUIDs subscribed to topic (empty set if none)
Example: (get-subscribers {"order:456" #{#uuid "111..." #uuid "222..."}} "order:456") => #{#uuid "111..." #uuid "222..."}
(get-subscribers {} "nonexistent") => #{}
Get all connection IDs subscribed to topic (pure).
Args:
subscriptions - Current subscriptions map
topic - Topic name string
Returns:
Set of connection UUIDs subscribed to topic (empty set if none)
Example:
(get-subscribers {"order:456" #{#uuid "111..." #uuid "222..."}}
"order:456")
=> #{#uuid "111..." #uuid "222..."}
(get-subscribers {} "nonexistent")
=> #{}(subscribe subscriptions connection-id topic)Add connection to topic subscribers (pure).
Subscriptions data structure is a map of topic to set of connection IDs: {"order:123" #{#uuid "conn-1" #uuid "conn-2"}}
Args: subscriptions - Current subscriptions map connection-id - UUID of connection to subscribe topic - Topic name string
Returns: Updated subscriptions map with connection added to topic
Example: (subscribe {} #uuid "123..." "order:456") => {"order:456" #{#uuid "123..."}}
(subscribe {"order:456" #{#uuid "111..."}} #uuid "222..." "order:456") => {"order:456" #{#uuid "111..." #uuid "222..."}}
Add connection to topic subscribers (pure).
Subscriptions data structure is a map of topic to set of connection IDs:
{"order:123" #{#uuid "conn-1" #uuid "conn-2"}}
Args:
subscriptions - Current subscriptions map
connection-id - UUID of connection to subscribe
topic - Topic name string
Returns:
Updated subscriptions map with connection added to topic
Example:
(subscribe {} #uuid "123..." "order:456")
=> {"order:456" #{#uuid "123..."}}
(subscribe {"order:456" #{#uuid "111..."}}
#uuid "222..."
"order:456")
=> {"order:456" #{#uuid "111..." #uuid "222..."}}(subscribed? subscriptions connection-id topic)Check if connection is subscribed to topic (pure).
Args: subscriptions - Current subscriptions map connection-id - UUID of connection topic - Topic name string
Returns: Boolean - true if connection is subscribed to topic
Example: (subscribed? {"order:456" #{#uuid "111..."}} #uuid "111..." "order:456") => true
(subscribed? {"order:456" #{#uuid "111..."}} #uuid "222..." "order:456") => false
Check if connection is subscribed to topic (pure).
Args:
subscriptions - Current subscriptions map
connection-id - UUID of connection
topic - Topic name string
Returns:
Boolean - true if connection is subscribed to topic
Example:
(subscribed? {"order:456" #{#uuid "111..."}}
#uuid "111..."
"order:456")
=> true
(subscribed? {"order:456" #{#uuid "111..."}}
#uuid "222..."
"order:456")
=> false(subscriber-count subscriptions)Count total number of subscriptions across all topics (pure).
Note: Same connection can be subscribed to multiple topics, so this may be greater than the number of unique connections.
Args: subscriptions - Current subscriptions map
Returns: Integer count of total subscriptions
Example: (subscriber-count {"order:456" #{#uuid "111..." #uuid "222..."} "user:789" #{#uuid "111..."}}) => 3 ; connection 111 counted twice (subscribed to 2 topics)
Count total number of subscriptions across all topics (pure).
Note: Same connection can be subscribed to multiple topics, so this
may be greater than the number of unique connections.
Args:
subscriptions - Current subscriptions map
Returns:
Integer count of total subscriptions
Example:
(subscriber-count {"order:456" #{#uuid "111..." #uuid "222..."}
"user:789" #{#uuid "111..."}})
=> 3 ; connection 111 counted twice (subscribed to 2 topics)(topic-count subscriptions)Count number of active topics (pure).
Args: subscriptions - Current subscriptions map
Returns: Integer count of topics with at least one subscriber
Example: (topic-count {"order:456" #{#uuid "111..."} "user:789" #{#uuid "222..."}}) => 2
Count number of active topics (pure).
Args:
subscriptions - Current subscriptions map
Returns:
Integer count of topics with at least one subscriber
Example:
(topic-count {"order:456" #{#uuid "111..."}
"user:789" #{#uuid "222..."}})
=> 2(topic-exists? subscriptions topic)Check if topic has any subscribers (pure).
Args: subscriptions - Current subscriptions map topic - Topic name string
Returns: Boolean - true if topic has at least one subscriber
Example: (topic-exists? {"order:456" #{#uuid "111..."}} "order:456") => true
(topic-exists? {} "nonexistent") => false
Check if topic has any subscribers (pure).
Args:
subscriptions - Current subscriptions map
topic - Topic name string
Returns:
Boolean - true if topic has at least one subscriber
Example:
(topic-exists? {"order:456" #{#uuid "111..."}} "order:456")
=> true
(topic-exists? {} "nonexistent")
=> false(unsubscribe subscriptions connection-id topic)Remove connection from topic subscribers (pure).
Args: subscriptions - Current subscriptions map connection-id - UUID of connection to unsubscribe topic - Topic name string
Returns: Updated subscriptions map with connection removed from topic. If topic has no more subscribers, topic key is removed from map.
Example: (unsubscribe {"order:456" #{#uuid "111..." #uuid "222..."}} #uuid "111..." "order:456") => {"order:456" #{#uuid "222..."}}
(unsubscribe {"order:456" #{#uuid "111..."}} #uuid "111..." "order:456") => {}
Remove connection from topic subscribers (pure).
Args:
subscriptions - Current subscriptions map
connection-id - UUID of connection to unsubscribe
topic - Topic name string
Returns:
Updated subscriptions map with connection removed from topic.
If topic has no more subscribers, topic key is removed from map.
Example:
(unsubscribe {"order:456" #{#uuid "111..." #uuid "222..."}}
#uuid "111..."
"order:456")
=> {"order:456" #{#uuid "222..."}}
(unsubscribe {"order:456" #{#uuid "111..."}}
#uuid "111..."
"order:456")
=> {}(unsubscribe-all subscriptions connection-id)Remove connection from all topics (pure).
Used when connection disconnects - clean up all subscriptions at once. Iterates through all topics and removes connection from each.
Args: subscriptions - Current subscriptions map connection-id - UUID of connection to unsubscribe from all topics
Returns: Updated subscriptions map with connection removed from all topics
Example: (unsubscribe-all {"order:456" #{#uuid "111..." #uuid "222..."} "user:789" #{#uuid "111..."}} #uuid "111...") => {"order:456" #{#uuid "222..."}}
Remove connection from all topics (pure).
Used when connection disconnects - clean up all subscriptions at once.
Iterates through all topics and removes connection from each.
Args:
subscriptions - Current subscriptions map
connection-id - UUID of connection to unsubscribe from all topics
Returns:
Updated subscriptions map with connection removed from all topics
Example:
(unsubscribe-all {"order:456" #{#uuid "111..." #uuid "222..."}
"user:789" #{#uuid "111..."}}
#uuid "111...")
=> {"order:456" #{#uuid "222..."}}cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |