MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / publish

Method publish

nodedb/src/control/pubsub.rs:180–237  ·  view source on GitHub ↗

Publish a message to a topic. Returns `(sequence_number, receivers)` where `receivers` is the count of broadcast subscribers + consumer groups that received the message.

(
        &self,
        topic_name: &str,
        payload: String,
        publisher: &str,
    )

Source from the content-addressed store, hash-verified

178 /// Returns `(sequence_number, receivers)` where `receivers` is the count of
179 /// broadcast subscribers + consumer groups that received the message.
180 pub fn publish(
181 &self,
182 topic_name: &str,
183 payload: String,
184 publisher: &str,
185 ) -> Result<(u64, usize), TopicError> {
186 let topics = super::lock_utils::read_or_recover(self.topics.read(), "topics");
187 let topic_mutex = topics
188 .get(topic_name)
189 .ok_or_else(|| TopicError::NotFound(topic_name.to_string()))?;
190 let mut topic = super::lock_utils::lock_or_recover(topic_mutex.lock(), "topic");
191
192 let seq = topic.next_seq;
193 topic.next_seq += 1;
194
195 let msg = PubSubMessage {
196 seq,
197 payload,
198 timestamp_ms: std::time::SystemTime::now()
199 .duration_since(std::time::UNIX_EPOCH)
200 .map(|d| d.as_millis() as u64)
201 .unwrap_or(0),
202 publisher: publisher.to_string(),
203 };
204
205 if topic.messages.len() >= topic.max_messages {
206 topic.messages.remove(0);
207 }
208 topic.messages.push(msg.clone());
209
210 // Deliver to broadcast subscribers. Remove dead channels.
211 let mut dead = Vec::new();
212 for (&sub_id, sender) in &topic.subscribers {
213 if sender.try_send(msg.clone()).is_err() {
214 debug!(
215 topic = topic_name,
216 sub_id, "subscriber channel full or closed; removing"
217 );
218 dead.push(sub_id);
219 }
220 }
221 for sub_id in dead {
222 topic.subscribers.remove(&sub_id);
223 }
224
225 // Count live broadcast subscribers (after removing dead ones).
226 let broadcast_count = topic.subscribers.len();
227
228 // Deliver to consumer groups (one member per group, round-robin).
229 let group_count = topic.consumer_groups.len();
230 for group in topic.consumer_groups.values_mut() {
231 group.deliver(&msg);
232 }
233
234 let receivers = broadcast_count + group_count;
235 debug!(topic = topic_name, seq, receivers, "message published");
236 Ok((seq, receivers))
237 }

Calls 15

read_or_recoverFunction · 0.85
lock_or_recoverFunction · 0.85
nowFunction · 0.85
to_stringMethod · 0.80
lockMethod · 0.80
duration_sinceMethod · 0.80
try_sendMethod · 0.80
deliverMethod · 0.80
readMethod · 0.45
getMethod · 0.45
as_millisMethod · 0.45
lenMethod · 0.45