Skip to content

Add retry logic, configurable timeouts, and client-side rate limiting to both SDKs#9

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/add-retry-logic-timeout-limiting
Draft

Add retry logic, configurable timeouts, and client-side rate limiting to both SDKs#9
Copilot wants to merge 2 commits intomainfrom
copilot/add-retry-logic-timeout-limiting

Conversation

Copy link

Copilot AI commented Feb 26, 2026

Both SDKs fail immediately on transient failures, have no configurable timeout (TypeScript has none at all), and provide no backoff strategy for consumers hitting distributed backends (AWS Lambda, GCF, Pipedream).

New CaptureOptions fields

Option TypeScript Python Default
Request timeout timeout (ms) timeout (s) 30s
Max retry attempts maxRetries max_retries 3
Initial backoff delay retryDelay (ms) retry_delay (s) 1s
Rate limit (req/s) rateLimit rate_limit none

Retry logic

  • Retries on HTTP 429, 500, 502, 503, 504 and network/connection errors
  • Exponential backoff: retryDelay * 2^(attempt-1) — 1s, 2s, 4s with defaults
  • Applied to all 5 API endpoints in both SDKs

Timeout

  • TypeScript: AbortController + setTimeout wrapping every fetch call
  • Python: httpx.Client constructed with configurable timeout

Rate limiting (token bucket)

  • Tokens refill at rateLimit per second; bucket starts full (burst capacity = rateLimit)
  • TypeScript: single-threaded, no locks needed
  • Python: threading.Lock-protected for thread-safe concurrent use
const capture = new Capture({
  token: 'my-token',
  timeout: 10_000,      // 10s per request
  maxRetries: 3,        // 3 retries with 1s/2s/4s backoff
  rateLimit: 5,         // max 5 req/s
})
capture = Capture(
    token="my-token",
    timeout=10.0,
    max_retries=3,
    retry_delay=1.0,
    rate_limit=5,
)
# or via CaptureOptions dataclass
opts = CaptureOptions(token="my-token", max_retries=5, rate_limit=10)
capture = Capture(options=opts)
Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature][High] Add retry logic, request timeout configuration, and client-side rate limiting</issue_title>
<issue_description>## Summary

The SDK currently lacks retry logic for transient network failures, configurable request timeouts, and client-side rate limiting. These are important for production resilience, especially given the SDK communicates with 5 distinct API endpoints across different providers (Numbers API, AWS Lambda, Google Cloud Functions, Pipedream).

Findings

1. No Retry Logic for Transient Failures

Python (python/numbersprotocol_capture/client.py, lines 184-209):

try:
    response = self._client.request(method, url, ...)
except httpx.RequestError as e:
    raise create_api_error(0, f"Network error: {e}", nid) from e

TypeScript (ts/src/client.ts, lines 176-193):

const response = await fetch(url, { method, headers, body: requestBody })

Both SDKs fail immediately on any network error. For production usage against distributed backends (AWS Lambda cold starts, GCF scaling), retrying on 429 (rate limit), 502/503/504 (transient server errors), and connection timeouts would significantly improve reliability.

2. Hardcoded Timeout (Python) / No Timeout (TypeScript)

Python (client.py, line 159):

self._client = httpx.Client(timeout=30.0)

The 30-second timeout is reasonable but not configurable by the caller.

TypeScript (client.ts, line 176):

const response = await fetch(url, { ... })

No timeout is configured at all — fetch will wait indefinitely by default, which can cause hanging requests in production.

3. No Client-Side Rate Limiting

Neither SDK implements rate limiting. If a consumer makes rapid successive calls (e.g., batch registration), they may overwhelm the backend APIs and receive 429 errors with no backoff strategy.

Suggested Implementation

Retry with Exponential Backoff

  • Retry on status codes: 429, 500, 502, 503, 504
  • Retry on network/connection errors
  • Max 3 retries with exponential backoff (1s, 2s, 4s)
  • Configurable via CaptureOptions (e.g., max_retries, retry_delay)

Configurable Timeout

  • Add timeout parameter to CaptureOptions (Python and TypeScript)
  • TypeScript: Use AbortController with setTimeout for fetch timeout
  • Default: 30 seconds (maintain current Python behavior)

Optional Rate Limiter

  • Simple token-bucket or sliding-window limiter
  • Configurable requests-per-second limit
  • Enabled via CaptureOptions (e.g., rate_limit: 10 for 10 req/s)

Expected Impact

  • Reliability: Significantly improves resilience against transient failures across 5 different backend services
  • Developer Experience: Reduces boilerplate — consumers won't need to implement their own retry/timeout logic
  • Production Readiness: Essential for any production deployment doing batch operations</issue_description>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…iting

Co-authored-by: numbers-official <181934381+numbers-official@users.noreply.github.com>
Copilot AI changed the title [WIP] Add retry logic and timeout configuration for SDK Add retry logic, configurable timeouts, and client-side rate limiting to both SDKs Feb 26, 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.

[Feature][High] Add retry logic, request timeout configuration, and client-side rate limiting

2 participants