// Enqueue send a message to the topic. All subscriptions receive a copy // of the message. func (t *Topic) Enqueue(f *frame.Frame) { switch t.subs.Len() { case 0: // no subscription, so do nothing case 1: // only one subscription, so can send the frame // without copying sub := t.subs.Front().Value.(Subscription) sub.SendTopicFrame(f) default: // more than one subscription, send clone for // all subscriptions except the last, which can // have the frame without copying for e := t.subs.Front(); e != nil; e = e.Next() { sub := e.Value.(Subscription) if e.Next() == nil { // the last in the list, send the frame // without copying sub.SendTopicFrame(f) } else { sub.SendTopicFrame(f.Clone()) } } } }
// Handle a SEND frame received from the client. Note that // this method is called after a SEND message is received, // but also after a transaction commit. func (c *Conn) handleSend(f *frame.Frame) error { // Send a receipt and remove the header err := c.sendReceiptImmediately(f) if err != nil { return err } if tx, ok := f.Header.Contains(frame.Transaction); ok { // the transaction header is removed from the frame err = c.txStore.Add(tx, f) if err != nil { return err } } else { // not in a transaction // change from SEND to MESSAGE f.Command = frame.MESSAGE c.requestChannel <- Request{Op: EnqueueOp, Frame: f} } return nil }