( ctx context.Context, req *common.NormalizedRequest, hedgeWrapped func(ctx context.Context) (*common.NormalizedResponse, error), )
| 176 | } |
| 177 | |
| 178 | func (e *upstreamExecutor) runRetry( |
| 179 | ctx context.Context, |
| 180 | req *common.NormalizedRequest, |
| 181 | hedgeWrapped func(ctx context.Context) (*common.NormalizedResponse, error), |
| 182 | ) (*common.NormalizedResponse, error) { |
| 183 | startTime := time.Now() |
| 184 | maxAttempts := 1 |
| 185 | if e.cfg != nil && e.cfg.Retry != nil && e.cfg.Retry.MaxAttempts > 0 { |
| 186 | maxAttempts = e.cfg.Retry.MaxAttempts |
| 187 | } |
| 188 | |
| 189 | var lastErr error |
| 190 | var lastResp *common.NormalizedResponse |
| 191 | retriesAttempted := 0 |
| 192 | for attempt := 0; attempt < maxAttempts; attempt++ { |
| 193 | if st := req.ExecState(); st != nil { |
| 194 | st.UpstreamAttempts.Add(1) |
| 195 | if attempt > 0 { |
| 196 | st.UpstreamRetries.Add(1) |
| 197 | } |
| 198 | } |
| 199 | resp, err := hedgeWrapped(ctx) |
| 200 | if attempt+1 >= maxAttempts || !e.shouldRetry(req, resp, err, attempt) { |
| 201 | if err != nil && retriesAttempted > 0 { |
| 202 | if lastResp != nil { |
| 203 | return lastResp, nil |
| 204 | } |
| 205 | return nil, common.NewErrFailsafeRetryExceeded(common.ScopeUpstream, err, &startTime) |
| 206 | } |
| 207 | return resp, err |
| 208 | } |
| 209 | lastErr = err |
| 210 | retriesAttempted++ |
| 211 | if resp != nil { |
| 212 | if lastResp != nil { |
| 213 | lastResp.Release() |
| 214 | } |
| 215 | lastResp = resp |
| 216 | } |
| 217 | |
| 218 | d := e.computeDelay(req, resp, err, attempt) |
| 219 | if d > 0 { |
| 220 | if serr := failsafe.SleepCtx(ctx, d); serr != nil { |
| 221 | return lastResp, serr |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | if lastErr != nil { |
| 227 | return lastResp, common.NewErrFailsafeRetryExceeded(common.ScopeUpstream, lastErr, &startTime) |
| 228 | } |
| 229 | return lastResp, nil |
| 230 | } |
| 231 | |
| 232 | func (e *upstreamExecutor) shouldRetry(req *common.NormalizedRequest, _ *common.NormalizedResponse, err error, _ int) bool { |
| 233 | if err == nil { |
no test coverage detected