Subscribe to a topic as a consumer group member. Messages are delivered to exactly ONE member of the group (round-robin). Multiple subscribers with the same `group_name` share the load. Returns (subscription_id, receiver, backlog).
(
&self,
topic_name: &str,
group_name: &str,
since_seq: u64,
)
| 279 | /// Multiple subscribers with the same `group_name` share the load. |
| 280 | /// Returns (subscription_id, receiver, backlog). |
| 281 | pub fn subscribe_group( |
| 282 | &self, |
| 283 | topic_name: &str, |
| 284 | group_name: &str, |
| 285 | since_seq: u64, |
| 286 | ) -> Result< |
| 287 | ( |
| 288 | u64, |
| 289 | tokio::sync::mpsc::Receiver<PubSubMessage>, |
| 290 | Vec<PubSubMessage>, |
| 291 | ), |
| 292 | TopicError, |
| 293 | > { |
| 294 | let topics = super::lock_utils::read_or_recover(self.topics.read(), "topics"); |
| 295 | let topic_mutex = topics |
| 296 | .get(topic_name) |
| 297 | .ok_or_else(|| TopicError::NotFound(topic_name.to_string()))?; |
| 298 | let mut topic = super::lock_utils::lock_or_recover(topic_mutex.lock(), "topic"); |
| 299 | |
| 300 | let sub_id = self.next_sub_id.fetch_add(1, Ordering::Relaxed); |
| 301 | let (tx, rx) = tokio::sync::mpsc::channel(256); |
| 302 | |
| 303 | let backlog = topic.get_backlog(since_seq); |
| 304 | |
| 305 | let group = topic |
| 306 | .consumer_groups |
| 307 | .entry(group_name.to_string()) |
| 308 | .or_insert_with(ConsumerGroup::new); |
| 309 | group.members.push((sub_id, tx)); |
| 310 | |
| 311 | debug!( |
| 312 | topic = topic_name, |
| 313 | group = group_name, |
| 314 | sub_id, |
| 315 | members = group.members.len(), |
| 316 | backlog = backlog.len(), |
| 317 | "subscribed to consumer group" |
| 318 | ); |
| 319 | Ok((sub_id, rx, backlog)) |
| 320 | } |
| 321 | |
| 322 | /// Unsubscribe from a topic. |
| 323 | pub fn unsubscribe(&self, topic_name: &str, sub_id: u64) { |