func (t *mockTransport) Send(req message.Request, timeout time.Duration) (message.Response, error) { id := req.Id() if id == "" { _uuid, err := uuid.NewV4() if err != nil { log.Errorf("[Typhon:MockTransport] Failed to generate request uuid: %v", err) return nil, err } req.SetId(_uuid.String()) } // Make a copy of the response that does not preserve the Body (this is not preserved over the wire) req = req.Copy() req.SetBody(nil) t.RLock() l, ok := t.listeners[req.Service()] t.RUnlock() if ok { responseChan := make(chan message.Response, 1) t.Lock() t.inflightReqs[req.Id()] = responseChan t.Unlock() defer func() { t.Lock() delete(t.inflightReqs, req.Id()) t.Unlock() }() timer := time.NewTimer(timeout) defer timer.Stop() select { case <-timer.C: log.Debugf("[Typhon:MockTransport] Timed out after %s waiting for delivery of \"%s\"", timeout.String(), req.Id()) return nil, transport.ErrTimeout case l.reqChan <- req: } select { case rsp := <-responseChan: return rsp, nil case <-timer.C: log.Debugf("[Typhon:MockTransport] Timed out after %s waiting for response to \"%s\"", timeout.String(), req.Id()) return nil, transport.ErrTimeout } } return nil, transport.ErrTimeout // Don't bother waiting artificially }