Skip to content

Tracking: one retry primitive for the patch API client (JSON, vendor service, blob and diff) #676

Description

[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: register comment.

Kind: tracking. Source: review Part 7.2 ("Three retry systems in one module") and R12; register row C15.

Problem

ApiClient has two independent retry policies. A third path, the blob and diff downloads, has none.

Path Policy Retryable Retry-After Jitter
JSON calls (send_json_request) api::retry: 3 retries, a run-wide 60 s window, SOCKET_API_MAX_RETRIES 429, 503 (retry.rs#L182-L187); #610 adds connect resets delta-seconds or HTTP-date (retry.rs#L193-L204) seeded SplitMix (retry.rs#L209)
Vendor service POST/GET and download_artifact (VendorRetryPolicy, vendor_backoff, download_artifact_capped) 3 attempts, 400 ms → 4 s, no env knob 429, 500, 502, 503, 504 + transport (client.rs#L327-L329) delta-seconds only (retry_after_secs) a second jitter_sample() built on RandomState (client.rs#L319-L324)
Blob and diff (fetch_binary, client.rs#L1066-L1124) none — — —

The same Socket hosts are therefore treated differently depending on the call. Shown by execution on 045d7ec (a temporary unit test, run twice, not committed), with Retry-After: Fri, 27 Mar 2026 19:12:42 GMT:

  • api::retry::parse_retry_after waits until that date;
  • the vendor path's retry_after_secs returns None and falls back to its own backoff;
  • 500, 502 and 504 are retried on vendor calls but are final on JSON calls.

Target design

One retry primitive in api::retry:

  • one Retry-After parser and one jitter source;
  • a Classifier per call family, since the retryable statuses legitimately differ (vendor archives build asynchronously, the patch API throttles);
  • one retry(op, policy, classifier) loop.

VendorRetryPolicy becomes a preset of that policy, not a second implementation, and fetch_binary gets the JSON preset. Timeouts stay where #581 put them (ApiTimeouts).

Checklist (each item one PR, in order)

Out of scope: the non-patch-API stacks (RegistryClient, self-update and telemetry clients). Telemetry's per-event client is C22.

Dependencies

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)priority:p3refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions