You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2272857
Browse filesBrowse the repository at this point in the historyBrowse files
t
committed
fix(node): cap per-request ipfs walk fan-out and sweep the ipfs limiter (#173)
Two review findings on the /ipfs/{cid} retrieval path.
Bound the full-history walk fan-out per request. The ipfs_rate_limiter check
fires once per request, but within a single request the object can exist under
path-scoped rules in many repos, and each distinct repo pays its own
spawn_blocking allowed-set walk (the memo only dedups the same repo). One
request could therefore fan out to O(repos) walks for a single rate-limiter
token (INV-10). Add MAX_HISTORY_WALKS_PER_REQUEST (16): once that many walks
have run, no further walk is spawned for the rest of the request. This also
closes jatmn's open P1 ("bound every full-history walk, not just the first
one").
The ceiling uses a plain break, not a whole-search break. The budget persists
across the outer oid-candidate loop, so a later candidate servable WITHOUT a
walk (a commit/tag, or a no-rule public copy) is still served, while any
further walk it would need re-trips the guard and is skipped. Breaking the
whole search would 404 that free candidate for no amplification benefit.
Sweep the ipfs limiter in the periodic cleanup task. ipfs_rate_limiter was the
one bounded limiter the 300s cleanup loop never called cleanup() on, so its map
sat full of stale source-IP entries until an inline capacity sweep reclaimed
them at the 200k cap. The six cleanup calls now live in
AppState::sweep_rate_limiters, which the loop drives, so the set is testable and
a new limiter has one place to be added.
Tests (each RED->GREEN verified by execution):
- ipfs_walk_fanout_capped_per_request: cap+1 deniers precede a readable copy;
capped -> 404, neutralizing the break -> 200.
- ipfs_walk_cap_still_serves_walk_free_candidate: a multi-oid CID whose blob
candidate burns the budget still serves its walk-free commit candidate (200);
a whole-search break -> 404.
- sweep_rate_limiters_includes_ipfs_limiter: drives the sweep and asserts the
ipfs limiter's expired entry is evicted; dropping its cleanup() -> entry
survives.
0 commit comments