Skip to content

Extract retry logic from BTQL into reusable utility#128

Merged
David Elner (delner) merged 1 commit intomainfrom
refactor/move_retry_logic_out_of_btql
Mar 23, 2026
Merged

Extract retry logic from BTQL into reusable utility#128
David Elner (delner) merged 1 commit intomainfrom
refactor/move_retry_logic_out_of_btql

Conversation

@delner
Copy link
Collaborator

BTQL#trace_spans previously owned retry-with-backoff logic that polled for fresh, non-empty results before returning. This had two problems:

  1. Unintended side effects for non-eval callers. Anyone querying BTQL outside of evals would hit up to ~39 seconds of sleep/retry delays they didn't ask for. Retry is an eval concern — the eval runner knows spans need time to settle after flush; the BTQL client shouldn't assume this.

  2. Not reusable. The backoff loop was hardcoded to BTQL-specific freshness semantics. Other code that needs retry-with-backoff had to reimplement it.

Changes

New Braintrust::Internal::Retry utility — a generic retry-with-backoff module. The block is the task; an optional until: lambda controls when to stop:

# Simple: retry until truthy
conn = Retry.with_backoff(max_retries: 5) { try_connect }

# With condition: caller decides what "done" means
result = Retry.with_backoff(until: ->(r) { r.ready? }) { api.fetch }

BTQL is now a stateless query client. trace_spans executes a single query and returns [rows, freshness]. No retry, no error swallowing. Errors propagate to the caller.

The eval runner owns retry policy. fetch_trace_spans wraps the BTQL call with Retry.with_backoff, using the freshness header to decide when results are ready. Error handling (log + return empty) also lives here.

Benefits

  • BTQL is safe to use outside evals without surprise delays
  • Retry logic is reusable across the SDK
  • Retry policy (timing, stop condition) is visible at the callsite, not buried in an API client
  • Separation of concerns: query client vs. retry policy vs. error handling

@delner David Elner (delner) force-pushed the refactor/move_retry_logic_out_of_btql branch from e75fc49 to 75be97e Compare March 23, 2026 14:43
@delner David Elner (delner) merged commit 00faf86 into main Mar 23, 2026
9 checks passed
@delner David Elner (delner) deleted the refactor/move_retry_logic_out_of_btql branch March 23, 2026 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants