Skip to content

fix(destinations): staged_upload/salesforce_bulk honor sync.retry and sync.rate_limit (#1048) - #1067

Merged
masukai merged 3 commits into
mainfrom
fix/1048-staged-retry-ratelimit
Sep 1, 2026
Merged

fix(destinations): staged_upload/salesforce_bulk honor sync.retry and sync.rate_limit (#1048)#1067
masukai merged 3 commits into
mainfrom
fix/1048-staged-retry-ratelimit

Conversation

@masukai

@masukai masukai commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #1048. StagedUploadDestination and SalesforceBulkDestination performed HTTP calls directly, bypassing sync.retry/sync.rate_limit entirely despite defining quota identities that imply those settings apply.

What changed

  • Added destination-level retry/rate_limit override fields to both config models, matching every other rate-limited destination.
  • Wired resolve_retry()/resolve_rate_limiter() + with_retry() into each destination's job-status polling leg only — the safe, idempotent part of the lifecycle.
  • Deliberately left unretried: stage/trigger/job-create/upload/close calls. Retrying these after an ambiguous failure (timeout, dropped connection after the server already processed it) could duplicate a job or upload. Flagging explicitly per the issue's own suggested direction rather than silently narrowing scope.
  • Added real behavioral tests for both destinations (retry-on-transient-failure, rate-limiter-acquire-per-check).

Note: unrelated pre-existing failure found while testing

Running the full local unit suite surfaced 2 failures in tests/unit/test_state_objectstore.py unrelated to this change — confirmed present on a clean origin/main checkout too. Filed separately as #1066 (hardcoded dates in a retention-prune test compared against the real wall clock — a time-bomb that just crossed a boundary). Not fixed here; out of scope.

Verification

Test plan

  • New retry/rate-limit tests pass for both destinations
  • Full unit suite otherwise green

🤖 Generated with Claude Code

… sync.rate_limit (#1048)

Wire the shared resolve_retry()/resolve_rate_limiter() helpers into the
safe, idempotent job-status polling legs of both destinations. Initial
stage/trigger/create/upload/close calls stay unretried since replaying
them after an ambiguous failure could duplicate jobs or uploads.

Retry-correctness fixes from adversarial review, folded in:
- Staged Upload retries only GET/HEAD polls; mutating poll methods
  execute once, since retrying them could replay a side effect.
- Every physical retry attempt acquires its own rate-limit slot,
  instead of one acquire covering all retries of one status check.
- Poll timeouts bound retry backoff and each request's own network
  timeout to the remaining budget, and reject a late-arriving success
  past the deadline.

Also regenerates the VS Code extension's bundled JSON schemas for the
new retry/rate_limit config fields (schema-drift CI check).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@masukai
masukai force-pushed the fix/1048-staged-retry-ratelimit branch from fdfa177 to 675b29c Compare September 1, 2026 03:02
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

masukai and others added 2 commits September 1, 2026 12:10
…ching CI

My local dev environment's pydantic (2.12.5) produced a different JSON
Schema shape for the destination union than a clean install resolves
(2.13.5, matching what CI's `uv pip install --system -e .` gets) —
the previously-committed bundled schema was already stale relative to
#997's callable-discriminator change, independent of this PR. Filed
#1070 to pin/stabilize this so it doesn't surprise future PRs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tween polls

Codecov flagged one uncovered line: staged_upload.py's poll loop
raising TimeoutError at the top of an iteration when the deadline has
already passed (e.g. an interval sleep after a non-terminal status
consumed the remaining budget), distinct from the already-covered
post-response deadline check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@masukai
masukai merged commit 2695380 into main Sep 1, 2026
10 checks passed
@masukai
masukai deleted the fix/1048-staged-retry-ratelimit branch September 1, 2026 03:40
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(destinations): staged_upload / salesforce_bulk bypass sync.retry and sync.rate_limit

1 participant