fix(selfhost): bound every Qdrant REST call with an AbortSignal timeout - #7106
Conversation
qdrant-vectorize.ts's 5 fetch() calls (initQdrantCollection's PUT + GET,
and upsert/query/deleteByIds) had no AbortSignal.timeout. This is a
self-host Node.js adapter with no platform-level subrequest ceiling, so an
unresponsive or partitioned Qdrant instance could hang these calls
indefinitely in the review/RAG pipeline -- unlike every other self-host
external-fetch adapter (ai.ts, review/**), which bound their fetches.
Add a shared QDRANT_FETCH_TIMEOUT_MS (15s) and pass
AbortSignal.timeout(...) to all 5 calls. The existing throw paths and
query's { matches: [] } degradation already handle a rejected fetch, so a
timeout surfaces exactly as any other network failure -- no new logic.
Closes JSONbored#7072
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7106 +/- ##
=======================================
Coverage 93.75% 93.75%
=======================================
Files 692 692
Lines 68808 68809 +1
Branches 18781 18781
=======================================
+ Hits 64511 64512 +1
Misses 3302 3302
Partials 995 995
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-17 23:09:48 UTC
Review summary Nits — 4 non-blocking
Flagged checks (non-blocking)
Decision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
What
src/selfhost/qdrant-vectorize.tsis a self-host Vectorize adapter backed by an operator's own Qdrant REST API. All 5 of itsfetch()calls —initQdrantCollection's PUT + GET, andupsert/query/deleteByIds— had noAbortSignal.timeout. This is a Node.js adapter with no platform-level subrequest ceiling (unlike the Workers runtime), so an unresponsive or network-partitioned Qdrant instance could hang these calls indefinitely in the review/RAG pipeline. Every other self-host external-fetch adapter (ai.ts,review/**) already uses a boundedAbortSignal.timeout.How
Add one module-scoped
QDRANT_FETCH_TIMEOUT_MS(15s, matching the siblings' order of magnitude) and passAbortSignal.timeout(QDRANT_FETCH_TIMEOUT_MS)to all 5 calls. Behavior on timeout is unchanged and correct by construction:upsert/deleteByIds/initQdrantCollectionalready throw on a non-ok/rejected fetch — anAbortSignalrejection propagates out ofawait fetch(...), firing those existing throw paths.query's existingtry/catchalready degrades to{ matches: [] }on any thrown error, so a timeout there degrades gracefully exactly like any other network failure.No new catch/throw logic — just the added
signal.Validation
Tests added to the existing
selfhost-qdrant-vectorize.test.ts: every Qdrant fetch across all 5 call sites (init PUT + GET, upsert, query, deleteByIds) is asserted to carry anAbortSignal. Confirmed they fail against the unfixed code and pass with the fix.typecheckclean; the adapter suite passes.Closes #7072