MiddleКодОчень частоЕщё не отвечали
Как написать helper ретраев только для transient-ошибок с exponential backoff, jitter и уважением ctx?
Реализуйте helper ретраев для идемпотентной операции. Он должен повторять только transient-ошибки, отступать экспоненциально, рандомизировать задержку, ограничивать число попыток и прерываться, как только ctx вызывающего завершён.
Ограничения:
- повторять только когда
isTransient(err)истинно; любая другая ошибка возвращается сразу - exponential backoff
base * 2^n(1s, 2s, 4s, ...) плюс случайный jitter, чтобы клиенты расцепились - остановиться после
maxAttemptsи вернуть последнюю ошибку - между попытками делать
selectпоctx.Done()— отменённый или истёкшийctxпрерывает и возвращаетctx.Err() - считайте, что
isTransient(error) boolуже дан
func retry(ctx context.Context, maxAttempts int, base time.Duration, op func() error) error {
// ваш код здесь
}
Напишите реализацию.
Крутите цикл до фиксированного лимита, вызывая op; при успехе верните nil, повторяйте только при transient-ошибке, иначе её верните. Между попытками спите base*2^n (1s, 2s, 4s) плюс случайный jitter и select по ctx.Done(), чтобы отменённый ctx прервал ожидание.
- ✗Повтор неидемпотентных или нетранзиентных ошибок — дублирование сайд-эффектов или долбёж по постоянному сбою
- ✗Backoff без jitter — все клиенты ретраят синхронно и создают согласованный thundering herd
- ✗Сон голым
time.Sleepбез учётаctx— отменённый вызов досиживает весь backoff
- →Зачем jitter вместо фиксированного сдвига между ретраями?
- →Как retry budget предотвращает усиление ретраев по цепочке?