Skip to content

fix: always close retry sleeper after delegate failure - #893

Open
sylvesterkaczmarek wants to merge 2 commits into
openai:mainfrom
sylvesterkaczmarek:fix/retrying-client-close-cleanup
Open

fix: always close retry sleeper after delegate failure#893
sylvesterkaczmarek wants to merge 2 commits into
openai:mainfrom
sylvesterkaczmarek:fix/retrying-client-close-cleanup

Conversation

@sylvesterkaczmarek

Copy link
Copy Markdown

Summary

Ensure RetryingHttpClient.close() always attempts to close its owned Sleeper, even when closing the delegate HttpClient throws.

Fixes #890.

Problem

RetryingHttpClient owns both its transport and sleeper, but currently closes them sequentially:

override fun close() {
    httpClient.close()
    sleeper.close()
}

If httpClient.close() throws, sleeper cleanup is skipped entirely.

The default sleeper owns a Timer, and custom sleepers can own other resources, so a transport cleanup failure can cause a second independent resource leak.

Fix

Mirror the failure-preserving cleanup pattern already used by AuthenticatingHttpClient:

  • attempt transport close first;
  • if it fails, still attempt sleeper close;
  • propagate the transport failure as the primary exception;
  • attach a distinct sleeper failure as suppressed;
  • when transport close succeeds, propagate any sleeper-close failure normally.

No retry execution behavior is changed.

Regression coverage

Added focused tests verifying:

  1. normal close closes both delegate and sleeper;
  2. delegate-close failure still closes the sleeper and remains the propagated failure;
  3. if both fail, the sleeper failure is attached as suppressed;
  4. a sleeper-only failure propagates normally after a successful delegate close.

Validation

  • branch is based on current upstream main at cf942a40074291290634321ad9fe21e514030b4c;
  • branch is 0 commits behind upstream;
  • production diff is 12 additions / 1 deletion in RetryingHttpClient.kt;
  • retry classification, backoff, request execution, and async behavior are unchanged.

Full repository validation is left to GitHub Actions.

Risk

Low. Successful close behavior is unchanged. The change only guarantees that both owned cleanup paths are attempted when one fails.

@sylvesterkaczmarek
sylvesterkaczmarek requested a review from a team as a code owner August 18, 2026 15:59
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.

RetryingHttpClient.close skips sleeper cleanup when delegate close fails

1 participant