Skip to content

Conversation

@jsklan
Copy link
Contributor

@jsklan jsklan commented Jan 27, 2026

Description

Refs: User-reported issue requesting exponential backoff retry logic for HTTP status codes (specifically 429 rate limit errors) to meet Square App Marketplace listing requirements.

Link to Devin run: https://app.devin.ai/sessions/5d7e9bfc387248cc89098c2b349cea6b
Requested by: @jsklan

This PR implements application-level retry logic with exponential backoff in the Ruby v2 SDK generator's RawClient, addressing a feature gap where the SDK previously only used Net::HTTP's network-level retries (which don't handle HTTP status codes like 429).

Update: Removed support for the non-standard X-RateLimit-Reset header as it has inconsistent unit implementations across different APIs, making it unreliable for retry timing.

Changes Made

  • Added retry loop in RawClient.send method that retries on specific HTTP status codes
  • Implemented exponential backoff with 20% jitter to prevent thundering herd
  • Added support for Retry-After header (both seconds and HTTP date formats)
  • Added support for X-RateLimit-Reset header (Unix timestamp) Removed - non-standard header with inconsistent implementations
  • Retryable status codes: [408, 429, 500, 502, 503, 504, 521, 522, 524] (matches legacy SDK)
  • Constants: INITIAL_RETRY_DELAY = 0.5s, MAX_RETRY_DELAY = 60s, JITTER_FACTOR = 0.2
  • Disabled Net::HTTP's built-in max_retries (set to 0) since we now handle retries at application level
  • Updated versions.yml with changelog entry for v1.0.0-rc82 (updated to reflect X-RateLimit-Reset removal)

Testing

  • Lint checks pass (pnpm run check)
  • Project compiles successfully
  • Unit tests added/updated (not added - Ruby v2 generator seed tests are in allowedFailures)
  • Manual code review of retry logic
  • Verified retry behavior with only standard Retry-After header support

Human Review Checklist

  • Verify retry status codes match requirements (legacy SDK compatibility)
  • Review decision to disable Net::HTTP.max_retries - this means network-level failures (connection timeouts) won't be retried by Net::HTTP anymore, only by our application-level logic which checks HTTP status codes
  • Verify jitter calculation produces expected range (±20% of delay)
  • Consider if the Retry-After header parsing handles edge cases correctly
  • Confirm removal of X-RateLimit-Reset header is appropriate (non-standard, inconsistent units)

…al backoff

- Add retry loop in RawClient.send method for HTTP status codes
- Support retryable statuses: 408, 429, 500, 502, 503, 504, 521, 522, 524
- Implement exponential backoff with jitter (20%)
- Respect Retry-After header (seconds or HTTP date format)
- Respect X-RateLimit-Reset header (Unix timestamp)
- Disable Net::HTTP network-level retries (max_retries=0) since we handle retries at application level
- Add constants: RETRYABLE_STATUSES, INITIAL_RETRY_DELAY, MAX_RETRY_DELAY, JITTER_FACTOR

This addresses the feature gap where the SDK previously only used Net::HTTP's
network-level retries, which don't handle HTTP status codes like 429 (Too Many
Requests). Enables compliance with rate-limiting requirements like Square App
Marketplace.

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@github-actions
Copy link
Contributor

🌱 Seed Test Selector

Select languages to run seed tests for:

  • Python
  • TypeScript
  • Java
  • Go
  • Ruby
  • C#
  • PHP
  • Swift
  • Rust
  • OpenAPI
  • Postman

How to use: Click the ⋯ menu above → "Edit" → check the boxes you want → click "Update comment". Tests will run automatically and snapshots will be committed to this PR.

Remove X-RateLimit-Reset header handling from retry logic as it's a non-standard
response header with inconsistent unit implementations across different APIs.
The retry logic now only respects the standard Retry-After header when determining
retry delays, falling back to exponential backoff with jitter.

Co-Authored-By: Claude Sonnet 4 <[email protected]>
Copy link
Member

@iamnamananand996 iamnamananand996 left a comment

Choose a reason for hiding this comment

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

Awesome

@fern-support fern-support merged commit 2accfd3 into main Jan 27, 2026
112 checks passed
@fern-support fern-support deleted the devin/1769473033-ruby-retry-backoff branch January 27, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants