Skip to content

fix(ferndesk): 429 backoff + slug cache (COR-444) - #14

Merged
echobt merged 1 commit into
mainfrom
fix/cor-444-ferndesk-ratelimit-cache
Sep 14, 2026
Merged

echobt merged 1 commit into
mainfrom
fix/cor-444-ferndesk-ratelimit-cache

Conversation

@echobt

@echobt echobt commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

COR-444 follow-up after #11#13:

  • CF 1010: fixed (curl_cffi)
  • Infinite /collections: fixed (section scope + guards)
  • Residual: FernDesk 429 rate_limited mid-upsert (34899748203)

This PR: longer 429 backoff (12 retries, up to 180s), slower create/update pacing, create-conflict recovery, limit=100 list pages, Actions cache for slug maps.

Note

FernDesk UI still needs Connect domain for docs.cortex.foundation HTTPS (separate from api CF 1010).

Test plan

  • Merge, wait for rate-limit cool-down, workflow_dispatch
  • SUMMARY with created/updated; no 1010

After CF 1010 and pagination fixes, sync creates articles then exhausts
FernDesk rate limits. Increase 429 retries/backoff, slow upsert pacing,
recover create conflicts via slug lookup+PATCH, request limit=100 pages,
and cache slug maps across Actions runs.
@mintlify

mintlify Bot commented Sep 14, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
cortex-foundation-add13747 🔴 Failed Sep 14, 2026, 9:45 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@echobt
echobt merged commit f2e9f08 into main Sep 14, 2026
@echobt
echobt deleted the fix/cor-444-ferndesk-ratelimit-cache branch September 14, 2026 21:44
echobt added a commit that referenced this pull request Sep 14, 2026
…444)

The write path (POST /articles, PATCH /articles/{id}, publish, collection
create) retried 429s with a fixed ladder and ignored Retry-After, so a
rate-limited run could stall or hang without reporting.

- Retry-After (delta-seconds or HTTP-date) now drives the wait when the
  server sends it and it exceeds the exponential backoff; values over 300s
  are treated as unusable and fall back to backoff.
- Bounded three ways: FERNDESK_WRITE_RETRIES (12/write),
  FERNDESK_WRITE_DEADLINE (1800s/write), FERNDESK_WRITE_BUDGET (5400s/run).
  Hard 4xx still fails fast without retrying.
- Retry logs name the article slug, status, and why it waited.
- A page that exhausts its retries no longer aborts the run: the sync
  continues, logs FAILURES, records failed/failed_slugs in SUMMARY, exits 1,
  and caches nothing for that slug so the next run retries cleanly.

Builds on the parallel COR-444 fix already on main (#14), which raised the
429 retry count and added a slower 429 cool-down. This keeps that 5s-to-180s
429 ladder and the create-conflict slug lookup + PATCH recovery, and layers
Retry-After handling, the per-write deadline, the run-wide budget, and honest
failure reporting on top. Pacing (1.2s/1.5s) and limit=100 pagination from
#14 are unchanged.

scripts/tests/ferndesk-sync-retry.test.py covers the policy offline (faked
transport, virtual clock) — 42 checks, including #14's conflict recovery —
and runs in the Docs site CI job.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
echobt added a commit that referenced this pull request Sep 14, 2026
…444) (#15)

The write path (POST /articles, PATCH /articles/{id}, publish, collection
create) retried 429s with a fixed ladder and ignored Retry-After, so a
rate-limited run could stall or hang without reporting.

- Retry-After (delta-seconds or HTTP-date) now drives the wait when the
  server sends it and it exceeds the exponential backoff; values over 300s
  are treated as unusable and fall back to backoff.
- Bounded three ways: FERNDESK_WRITE_RETRIES (12/write),
  FERNDESK_WRITE_DEADLINE (1800s/write), FERNDESK_WRITE_BUDGET (5400s/run).
  Hard 4xx still fails fast without retrying.
- Retry logs name the article slug, status, and why it waited.
- A page that exhausts its retries no longer aborts the run: the sync
  continues, logs FAILURES, records failed/failed_slugs in SUMMARY, exits 1,
  and caches nothing for that slug so the next run retries cleanly.

Builds on the parallel COR-444 fix already on main (#14), which raised the
429 retry count and added a slower 429 cool-down. This keeps that 5s-to-180s
429 ladder and the create-conflict slug lookup + PATCH recovery, and layers
Retry-After handling, the per-write deadline, the run-wide budget, and honest
failure reporting on top. Pacing (1.2s/1.5s) and limit=100 pagination from
#14 are unchanged.

scripts/tests/ferndesk-sync-retry.test.py covers the policy offline (faked
transport, virtual clock) — 42 checks, including #14's conflict recovery —
and runs in the Docs site CI job.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
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.

2 participants