Skip to content

fix(transport): add SSE keepalive and configure HTTP server timeouts for proxy chain#147

Merged
polaz merged 1 commit intomainfrom
feat/#139-fixtransport-add-sse-keepalive-and-configure-http
Jan 23, 2026
Merged

fix(transport): add SSE keepalive and configure HTTP server timeouts for proxy chain#147
polaz merged 1 commit intomainfrom
feat/#139-fixtransport-add-sse-keepalive-and-configure-http

Conversation

@polaz
Copy link
Copy Markdown
Member

@polaz polaz commented Jan 23, 2026

Summary

  • Add SSE heartbeat (: ping\n\n comments every 30s) to keep connections alive through Cloudflare/Envoy proxy chains that kill idle SSE streams after ~125s
  • Configure HTTP server timeouts (keepAliveTimeout=620s, headersTimeout=625s, timeout=0) to prevent Node.js from closing connections before upstream proxies
  • Both values configurable via GITLAB_SSE_HEARTBEAT_MS and GITLAB_HTTP_KEEPALIVE_TIMEOUT_MS environment variables
  • Heartbeat applied to both legacy /sse and modern StreamableHTTP GET endpoints

Changes

  • src/config.ts — Add SSE_HEARTBEAT_MS and HTTP_KEEPALIVE_TIMEOUT_MS config with env var parsing
  • src/server.ts — Add startSseHeartbeat() helper, configureServerTimeouts(), integrate into both SSE endpoints, use http.createServer() for proper timeout control
  • tests/unit/server.test.ts — 10 new tests covering heartbeat start/stop/ping, GET SSE streams, POST non-heartbeat, HTTP timeout configuration

Test plan

  • All 3685 unit tests pass
  • ESLint passes with 0 errors
  • TypeScript compilation succeeds
  • Build succeeds
  • Deploy to staging and verify SSE connections survive >125s idle time
  • Verify Envoy access logs show non-zero response body bytes (heartbeat data)
  • Verify DR (Downstream Reset) flags no longer appear at ~125s

Closes #139

…for proxy chain

SSE connections through Cloudflare → Envoy → Node.js are killed after
~125s of idle time. This adds two fixes:

1. SSE heartbeat: sends `: ping\n\n` comments every 30s (configurable
   via GITLAB_SSE_HEARTBEAT_MS) to keep connections alive through proxies.
   Applied to both legacy /sse and modern StreamableHTTP GET endpoints.

2. HTTP server timeouts: configures keepAliveTimeout (620s), headersTimeout
   (625s), and timeout (0) to prevent Node.js from closing connections
   before upstream proxies do. Configurable via GITLAB_HTTP_KEEPALIVE_TIMEOUT_MS.

Closes #139
Copilot AI review requested due to automatic review settings January 23, 2026 16:44
@github-actions
Copy link
Copy Markdown

Test Coverage Report

Overall Coverage: 93.18%

Metric Percentage
Statements 92.69%
Branches 84.23%
Functions 82.55%
Lines 93.18%

View detailed coverage report

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 88.23529% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/config.ts 71.42% 0 Missing and 2 partials ⚠️
src/server.ts 92.59% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a critical production issue where SSE connections through proxy chains (Cloudflare → Envoy → Node.js) are killed after approximately 125 seconds of idle time. The fix implements two complementary solutions: SSE heartbeat keepalives and proper HTTP server timeout configuration.

Changes:

  • Added configurable SSE heartbeat mechanism sending : ping\n\n comments every 30 seconds to keep connections alive through proxies
  • Configured HTTP server timeouts (keepAliveTimeout=620s, headersTimeout=625s, timeout=0) to prevent Node.js from closing connections before upstream proxies
  • Applied heartbeat to both legacy /sse endpoint and modern StreamableHTTP GET endpoints with proper cleanup on connection close

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/config.ts Added SSE_HEARTBEAT_MS and HTTP_KEEPALIVE_TIMEOUT_MS configuration with environment variable parsing and validation
src/server.ts Implemented startSseHeartbeat() helper, configureServerTimeouts(), integrated heartbeat into both SSE endpoints, and switched to http.createServer() for timeout control
tests/unit/server.test.ts Added 10 comprehensive unit tests covering heartbeat lifecycle, ping delivery, cleanup, and HTTP timeout configuration

@polaz polaz merged commit 382490b into main Jan 23, 2026
25 checks passed
@polaz polaz deleted the feat/#139-fixtransport-add-sse-keepalive-and-configure-http branch January 23, 2026 18:09
sw-release-bot bot pushed a commit that referenced this pull request Jan 23, 2026
## [6.31.2](v6.31.1...v6.31.2) (2026-01-23)

### Bug Fixes

* **transport:** add SSE keepalive and configure HTTP server timeouts for proxy chain ([#147](#147)) ([382490b](382490b)), closes [#139](#139)
@sw-release-bot
Copy link
Copy Markdown

🎉 This PR is included in version 6.31.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(transport): add SSE keepalive and configure HTTP server timeouts for proxy chain

2 participants