MCPcopy Create free account
hub / github.com/erpc/erpc / runRetry

Method runRetry

erpc/network_executor.go:205–349  ·  view source on GitHub ↗
(
	ctx context.Context,
	req *common.NormalizedRequest,
	hedged func(ctx context.Context) (*common.NormalizedResponse, error),
)

Source from the content-addressed store, hash-verified

203}
204
205func (e *networkExecutor) runRetry(
206 ctx context.Context,
207 req *common.NormalizedRequest,
208 hedged func(ctx context.Context) (*common.NormalizedResponse, error),
209) (*common.NormalizedResponse, error) {
210 maxAttempts := 1
211 if e.cfg != nil && e.cfg.Retry != nil && e.cfg.Retry.MaxAttempts > 0 {
212 maxAttempts = e.cfg.Retry.MaxAttempts
213 }
214 startTime := time.Now()
215 st := req.ExecState()
216
217 var bestResp *common.NormalizedResponse
218 var lastErr error
219 // firstInformativeErr captures the first attempt's error that
220 // contains real upstream details (ErrUpstreamsExhausted with
221 // children, ErrExecutionException, etc.) — subsequent retry
222 // attempts can degenerate into bare ErrNoUpstreamsLeftToSelect
223 // which loses that info; the final wrap uses this instead.
224 var firstInformativeErr error
225 retriesAttempted := 0
226
227 for attempt := 0; attempt < maxAttempts; attempt++ {
228 // Bail out early if the lifecycle context has fired — the timeout
229 // owns the classification, not retry-exhausted.
230 if ctxErr := ctx.Err(); ctxErr != nil {
231 cause := context.Cause(ctx)
232 if cause != nil {
233 return bestResp, cause
234 }
235 return bestResp, ctxErr
236 }
237
238 if attempt > 0 && st != nil {
239 st.NetworkRetries.Add(1)
240 retriesAttempted++
241 }
242 if st != nil {
243 st.NetworkAttempts.Add(1)
244 }
245
246 resp, err := hedged(ctx)
247
248 // If the lifecycle context fired during the attempt, surface the
249 // ctx cause directly instead of wrapping as retry-exhausted.
250 if ctxErr := ctx.Err(); ctxErr != nil {
251 cause := context.Cause(ctx)
252 if cause != nil {
253 return bestResp, cause
254 }
255 return bestResp, ctxErr
256 }
257
258 // If this is the last attempt OR shouldRetry says no, return.
259 retryReason := ""
260 if attempt+1 < maxAttempts {
261 retryReason = e.shouldRetryWithReason(req, resp, err, attempt)
262 }

Callers 1

runRetryHedgeMethod · 0.95

Calls 15

shouldRetryWithReasonMethod · 0.95
ReleaseMethod · 0.95
computeDelayMethod · 0.95
HasErrorCodeFunction · 0.92
SleepCtxFunction · 0.92
isDataUnavailableReasonFunction · 0.85
ExecStateMethod · 0.80
MethodMethod · 0.80
AddMethod · 0.65
WithLabelValuesMethod · 0.65
ProjectIdMethod · 0.65
NetworkLabelMethod · 0.65

Tested by

no test coverage detected