in forward/request_sender.go [100:157]
func (s *requestSender) Send() (res []byte, err error) {
var cancel context.CancelFunc
var ctx thrift.Context
if s.ctx == nil {
ctx, cancel = shared.NewTChannelContext(s.timeout)
} else {
var c context.Context
c, cancel = context.WithTimeout(s.ctx, s.timeout)
ctx = tchannel.Wrap(c)
}
defer cancel()
var forwardError, applicationError error
select {
case <-s.MakeCall(ctx, &res, &forwardError, &applicationError):
if applicationError != nil {
return nil, applicationError
}
if forwardError == nil {
if s.retries > 0 {
// forwarding succeeded after retries
s.emitter.EmitEvent(RetrySuccessEvent{s.retries})
}
return res, nil
}
if s.retries < s.maxRetries {
return s.ScheduleRetry()
}
address, _ := s.sender.WhoAmI()
s.logger.WithFields(log.Fields{
"local": address,
"destination": s.destination,
"service": s.service,
"endpoint": s.endpoint,
}).Warn("max retries exceeded for request")
s.emitter.EmitEvent(MaxRetriesEvent{s.maxRetries})
return nil, errors.New("max retries exceeded")
case <-ctx.Done(): // request timed out
address, _ := s.sender.WhoAmI()
s.logger.WithFields(log.Fields{
"local": address,
"destination": s.destination,
"service": s.service,
"endpoint": s.endpoint,
}).Warn("request timed out")
return nil, errors.New("request timed out")
}
}