Ejemplo n.º 1
0
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
}