Deduplicate ipfs-retriever candidates by service provider - #689
Deduplicate ipfs-retriever candidates by service provider#689juliangruber wants to merge 1 commit into
Conversation
One IPFS root CID can map to many pieces (shards) on the same service provider. Retrieval is by root CID and never uses the piece, so those candidates are identical retrieval requests. Keep one candidate per service provider so a failing provider is attempted once rather than once per shard, while still retrying across distinct providers.
Can we deduplicate at the SQL level?Technically yes, with a Dedup must happen after authorization, not beforeA group of "same If we To dedup safely in SQL we'd have to push the whole auth and quota filter into the query: SELECT service_provider_id, service_url, data_set_id, piece_id, ipfs_root_cid, ...
FROM pieces
JOIN data_sets ON ...
JOIN service_providers ON ...
LEFT JOIN data_set_egress_quotas ON ...
LEFT JOIN wallet_details ON ...
WHERE pieces.ipfs_root_cid = ?
AND pieces.is_deleted IS FALSE
AND service_providers.id IS NOT NULL AND service_providers.is_deleted IS FALSE
AND LOWER(data_sets.payer_address) = ?
AND data_sets.with_cdn = 1
AND COALESCE(wallet_details.is_sanctioned, 0) = 0
AND (NOT ? OR (COALESCE(cdn_egress_quota, 0) > 0 AND COALESCE(cache_miss_egress_quota, 0) > 0))
GROUP BY service_provider_id -- or ROW_NUMBER() OVER (PARTITION BY service_provider_id) = 1Why that's a net loss
RecommendationKeep the dedup in JS. It's trivially correct because it runs on the post-authorization set, it preserves the specific error responses, and it fully fixes the redundant-retry problem. SQL-level dedup would only pay off if shard counts got large enough that transferring the rows mattered, and even then the right lever is the index plus maybe a |
Stacked on #312.
Closes #691
Addresses #312 (comment).
Problem
ipfs-retrieverlooks up candidates withWHERE pieces.ipfs_root_cid = ?, returning one row per piece. Under Storacha's sharding model one IPFS root CID maps to N pieces (shards) on the same service provider, so the lookup yields N candidates that differ only by piece, all with the sameserviceUrl.Retrieval is by IPFS root CID through the trustless gateway.
retrieveIpfsContentuses onlyserviceUrlandipfsRootCid, never the piece, so every one of those candidates is the exact same HTTP request.selectRetrievalCandidatethen retries across all N on failure, hitting a genuinely failing provider N times before returning the 502.Fix
Deduplicate candidates by service provider in
validateQueryResultsAndGetCandidates, after the authorization and quota cascade. A failing provider is now attempted once rather than once per shard, while retries across distinct providers (content replicated across providers) are preserved. This also makes the code match the existing JSDoc, which already documents "one per service provider".The dedup lives in the
ipfs-retrieverlookup rather than the sharedselectRetrievalCandidate, becausepiece-retrieverretrieves by piece CID, where candidates sharing aserviceUrlare distinct requests and must not be collapsed.