Add per-endpoint timeout configuration so one slow dependency cannot exhaust the request pool
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- aws, azure, docker-compose, elasticsearch, kubernetes, nodejs, typescript
- Domain
- backend, observability, performance
Research direction
Start with the existing timeout in src/health/health.service.ts, then look at the interceptors folder under src/common/ and the outbound clients in src/search/search.service.ts and src/infrastructure/file-upload/services/file-storage.service.ts. Check docker-compose.yml and docs/kubernetes-health-probes.md for proxy timeouts. Done means a global timeout returns a distinct 503 or 504 with an error code, WebSocket handlers are excluded, and tests cover timeout, success, and rollback of a timed-out write.
Written by the indexing model from the issue text.
Description
Problem
There is no request timeout configuration. src/health/health.service.ts:22-24 reads a timeout for health checks only:
this.timeoutMs =
this.configService.get<number>("HEALTH_CHECK_TIMEOUT_MS") ?? 5000;
Nothing equivalent protects the request path. Many endpoints make outbound calls — Elasticsearch (src/search/search.service.ts), the AI providers behind the compute bridge, Stellar/Horizon (src/reconciliation/horizon-polling.service.ts), S3 and Azure Blob (src/infrastructure/file-upload/services/file-storage.service.ts), and email (src/email/services/).
If any of those hangs, the HTTP request hangs with it, holding a Node event-loop slot and a socket until the platform's own idle timeout fires — which for many hosts is 60s or longer.
Why it matters
A single slow dependency degrades the whole service rather than one endpoint, because there is no bound on how long a handler may take. Under a partial outage the effect is a connection-pool exhaustion cascade: requests queue behind each other, latency climbs, and the service appears down even though the process is healthy. This is the classic failure mode described in the README's operational notes ("monitor... latency spikes", line 259).
Suggested Direction
- Add a global request timeout interceptor in
src/common/interceptors/, wrappingnext.handle()in a race against a timer that throws aRequestTimeoutException. Make the default configurable (REQUEST_TIMEOUT_MS), and allow per-route overrides with a@RequestTimeout(ms)decorator. - Make the global value generous and the per-route values tight. External provider calls need their own shorter budgets — set explicit timeouts on the outbound clients too (Elasticsearch
requestTimeout, axiostimeout, the S3/Azure SDK clients), since a client-side timeout is what actually frees the socket. - Do not forget the streaming and WebSocket paths.
src/dashboard/websocket/should not be subject to an HTTP request timeout at all; exclude gateway handlers explicitly. - Return
503(or504) with a clear error code on timeout rather than a generic 500, so clients and dashboards can distinguish a timeout from a bug. - Emit a metric on timeout so slow dependencies are visible before they become an incident.
Constraints
- A timeout must not leave partial work committed. For endpoints that write, ensure the transaction is rolled back — this matters most for the on-chain submission path.
- Bull queue workers have their own concurrency and lock semantics; make sure job handlers are not accidentally cut off by an HTTP-shaped timeout.
- Keep the timeout well below the reverse-proxy timeout, or the proxy will return 504 before the app does — check
docker-compose.ymland the Kubernetes probes indocs/kubernetes-health-probes.md. - Timeouts are operational tuning; make them configurable rather than hardcoded.
Acceptance Criteria
- A global request timeout exists and is configurable via env.
- Outbound HTTP/database clients have their own timeouts configured.
- Timeouts return a distinct, documented status code and error body.
- WebSocket gateway handlers are excluded.
- At least one endpoint demonstrates a tightened per-route timeout.
- Tests cover: timeout triggering, the success path, and that a timed-out write leaves no partial state.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 55
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 5
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SourceXXL/alian_structure-api
-
good first issue help wanted security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#266 ·
-
Parallelize the cache-warming loop in `cache-warming.service.ts` — warmers run strictly sequentiallyMay be free again @syntaxsuuvam-spec claimed this 18 days ago, and no pull request is open. Opengood first issue performance
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#240 ·
-
documentation help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
SourceXXL/alian_structure-api#215 ·
-
good first issue refactor tooling
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
SourceXXL/alian_structure-api#199 ·
-
help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
SourceXXL/alian_structure-api#196 ·
All issues in SourceXXL/alian_structure-api
Similar issues
-
area:plugins area:security area:skills bug has repro
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
anthropics/claude-code#105911 ·
Maintainers usually reply within 1 day
-
openspec-apply-change skill: when blocked, may select a ready artifact unrelated to missingArtifactsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Fission-AI/OpenSpec#2165 ·
Maintainers usually reply within 1 day
-
🐞 bug 🧐 unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Tencent/tdesign-vue-next#7032 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gnosis/gnosis_vpn#661 ·
Maintainers usually reply within 1 day
-
content-freshness: staleOwnedContent doc comments still say 'complete receipt' (follow-up to #7912)Opentriage:bug-verified
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Maintainers usually reply within 1 day