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 *star) SendHook(m *mangos.Message) bool { if x.raw { // TTL header must be present. return true } // new message has a zero hop count m.Header = append(m.Header, 0, 0, 0, 0) return true }
// We save the backtrace from this message. This means that if the app calls // Recv before calling Send, the saved backtrace will be lost. This is how // the application discards / cancels a request to which it declines to reply. // This is only done in cooked mode. func (r *rep) RecvHook(m *mangos.Message) bool { if r.raw { return true } r.sock.SetSendError(nil) r.backtraceL.Lock() r.backtrace = append(r.backtracebuf[0:0], m.Header...) r.backtraceL.Unlock() m.Header = nil return true }
func (x *resp) SendHook(m *mangos.Message) bool { if x.raw { // Raw mode senders expected to have prepared header already. return true } x.sock.SetSendError(mangos.ErrProtoState) x.Lock() m.Header = append(m.Header[0:0], x.backtrace...) x.backtrace = nil x.Unlock() if len(m.Header) == 0 { return false } return true }
func (x *surveyor) RecvHook(m *mangos.Message) bool { if x.raw { return true } x.Lock() defer x.Unlock() if len(m.Header) < 4 { return false } if binary.BigEndian.Uint32(m.Header) != x.surveyID { return false } m.Header = m.Header[4:] return true }
func (r *rep) SendHook(m *mangos.Message) bool { // Store our saved backtrace. Note that if none was previously stored, // there is no one to reply to, and we drop the message. We only // do this in cooked mode. if r.raw { return true } r.sock.SetSendError(mangos.ErrProtoState) r.backtraceL.Lock() m.Header = append(m.Header[0:0], r.backtrace...) r.backtrace = nil r.backtraceL.Unlock() if m.Header == nil { return false } return true }
func (r *rep) sender() { defer r.w.Done() sq := r.sock.SendChannel() cq := r.sock.CloseChannel() for { var m *mangos.Message select { case m = <-sq: case <-cq: return } // Lop off the 32-bit peer/pipe ID. If absent, drop. if len(m.Header) < 4 { m.Free() continue } id := binary.BigEndian.Uint32(m.Header) m.Header = m.Header[4:] r.Lock() pe := r.eps[id] r.Unlock() if pe == nil { m.Free() continue } select { case pe.q <- m: default: // If our queue is full, we have no choice but to // throw it on the floor. This shoudn't happen, // since each partner should be running synchronously. // Devices are a different situation, and this could // lead to lossy behavior there. Initiators will // resend if this happens. Devices need to have deep // enough queues and be fast enough to avoid this. m.Free() } } }
func (x *resp) sender() { // This is pretty easy because we have only one peer at a time. // If the peer goes away, we'll just drop the message on the floor. defer x.w.Done() cq := x.sock.CloseChannel() sq := x.sock.SendChannel() for { var m *mangos.Message select { case m = <-sq: case <-cq: return } // Lop off the 32-bit peer/pipe ID. If absent, drop. if len(m.Header) < 4 { m.Free() continue } id := binary.BigEndian.Uint32(m.Header) m.Header = m.Header[4:] x.Lock() peer := x.peers[id] x.Unlock() if peer == nil { m.Free() continue } // Put it on the outbound queue select { case peer.q <- m: default: // Backpressure, drop it. m.Free() } } }
func (x *surveyor) SendHook(m *mangos.Message) bool { if x.raw { return true } x.Lock() x.surveyID = x.nextID | 0x80000000 x.nextID++ x.sock.SetRecvError(nil) v := x.surveyID m.Header = append(m.Header, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) if x.duration > 0 { x.timer.Reset(x.duration) } x.Unlock() return true }
func (x *bus) RecvHook(m *mangos.Message) bool { if !x.raw && len(m.Header) >= 4 { m.Header = m.Header[4:] } return true }