func (r *req) SendHook(m *mangos.Message) bool { if r.raw { // Raw mode has no automatic retry, and must include the // request id in the header coming down. return true } r.Lock() defer r.Unlock() // We need to generate a new request id, and append it to the header. r.reqid = r.nextID() v := r.reqid m.Header = append(m.Header, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) r.reqmsg = m.Dup() // Schedule a retry, in case we don't get a reply. if r.retry > 0 { r.waker.Reset(r.retry) } else { r.waker.Stop() } r.sock.SetRecvError(nil) return true }
func (x *bus) broadcast(m *mangos.Message, sender uint32) { x.Lock() for id, pe := range x.peers { if sender == id { continue } m = m.Dup() select { case pe.q <- m: default: // No room on outbound queue, drop it. // Note that if we are passing on a linger/shutdown // notification and we can't deliver due to queue // full, it means we will wind up waiting the full // linger time in the lower sender. Its correct, if // suboptimal, behavior. m.Free() } } x.Unlock() }
func (x *star) broadcast(m *mangos.Message, sender *starEp) { x.Lock() if sender == nil || !x.raw { for _, pe := range x.eps { if sender == pe { continue } m = m.Dup() select { case pe.q <- m: default: // No room on outbound queue, drop it. if m != nil { m.Free() } } } } x.Unlock() // Grab a local copy and send it up if we aren't originator if sender != nil { select { case x.sock.RecvChannel() <- m: case <-x.sock.CloseChannel(): m.Free() return default: // No room, so we just drop it. m.Free() } } else { // Not sending it up, so we need to release it. m.Free() } }
func (x *surveyor) sender() { defer x.w.Done() sq := x.sock.SendChannel() cq := x.sock.CloseChannel() for { var m *mangos.Message select { case m = <-sq: case <-cq: return } x.Lock() for _, pe := range x.peers { m := m.Dup() select { case pe.q <- m: default: m.Free() } } x.Unlock() } }