Skip to content

Fix TimeoutOverflowWarning in retry strategy#568

Merged
polRk merged 2 commits intoydb-platform:mainfrom
DanilTezin:fix-retry-timeout-overflow
Mar 11, 2026
Merged

Fix TimeoutOverflowWarning in retry strategy#568
polRk merged 2 commits intoydb-platform:mainfrom
DanilTezin:fix-retry-timeout-overflow

Conversation

@DanilTezin
Copy link
Contributor

@DanilTezin DanilTezin commented Mar 10, 2026

Root cause:
In packages/retry/src/index.ts, defaultRetryConfig uses exponential(ms) which computes 2^attempt * ms.

exponential(ms) вычисляет 2^attempt * ms без ограничения сверху. После достаточного числа попыток результат становится Infinity, которое передаётся в setTimeout. Node.js не умеет работать с таким значением, выбрасывает TimeoutOverflowWarning и сбрасывает задержку до 1 мс — retry-цикл превращается в busy loop.

Исправление: заменить на уже существующую функцию backoff(base, max) из strategy.ts, которая ограничивает результат через Math.min(2^attempt * base, max).

  • OVERLOADED / RESOURCE_EXHAUSTEDbackoff(1000, 60_000)
  • дефолтный случай и stream CANCELLED|UNAVAILABLEbackoff(10, 30_000)

Добавлены тесты, которые проверяют что задержка никогда не превышает заданный максимум.

@DanilTezin
Copy link
Contributor Author

Issue где описан подобный случай ошибки - #536

Replace exponential(ms) with backoff(base, max) in defaultRetryConfig
and defaultStreamRetryConfig. exponential() grows unbounded and reaches
Infinity after enough retries, causing Node.js to emit
TimeoutOverflowWarning and reset setTimeout to 1ms — a busy loop.

New caps:
- OVERLOADED / RESOURCE_EXHAUSTED: backoff(1000, 60_000)
- default / stream CANCELLED|UNAVAILABLE: backoff(10, 30_000)

Add tests verifying the computed delay never exceeds the configured max.
@DanilTezin DanilTezin force-pushed the fix-retry-timeout-overflow branch from 7a16410 to 83c864a Compare March 10, 2026 21:27
@goodok21
Copy link

@ydb-platform-bot

Copy link
Member

@polRk polRk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно еще файлик changeset создать, для версионирования


if (ctx.error instanceof YDBError && ctx.error.code === StatusIds_StatusCode.OVERLOADED) {
return exponential(1000)(ctx, cfg)
return backoff(1000, 60_000)(ctx, cfg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно вынести эти магические констнты вверх файла.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@DanilTezin DanilTezin requested a review from polRk March 11, 2026 12:48
@polRk polRk merged commit fbf2c6b into ydb-platform:main Mar 11, 2026
5 checks passed
@github-actions github-actions bot mentioned this pull request Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants