fix: release homer sockets when a pcap request is abandoned (#565)

The pcap route awaited homer with no timeout and no tie to the client
connection, then used stream.pipe(res). If the client gave up (nginx 499)
before homer answered, the homer response body was piped into a closed
response, pipe() detached without destroying it, and the unread body kept
its socket and buffers referenced by the global undici pool forever.

With homer slow, this leaked roughly one socket per abandoned request:
~1,300 open fds and +200 MB RSS per api-server worker within four hours.

- abort the homer auth and pcap fetches when the response closes or after 30s
- use stream.pipeline() so the homer stream is destroyed if the client leaves

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dave HortonandClaude Opus 5.5 authored and GitHub committed 2026-10-07 17:04:33 -06:00
1 parent c55819a068
commit 328087042f
2 files changed
+25 -5

No files matched your search

+4 -2
View File
@@ -7,13 +7,14 @@ const { Readable } = require('stream');
const SEVEN_DAYS_IN_MS = (1000 * 3600 * 24 * 7);
const HOMER_BASE_URL = process.env.HOMER_BASE_URL || 'http://127.0.0.1';
const getHomerApiKey = async(logger) => {
const getHomerApiKey = async(logger, signal) => {
if (!process.env.HOMER_BASE_URL || !process.env.HOMER_USERNAME || !process.env.HOMER_PASSWORD) {
logger.debug('getHomerApiKey: Homer integration not installed');
}
try {
const response = await fetch(`${HOMER_BASE_URL}/api/v3/auth`, {
signal,
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -82,13 +83,14 @@ const getHomerSipTrace = async(logger, apiKey, callId) => {
}
};
const getHomerPcap = async(logger, apiKey, callIds, method) => {
const getHomerPcap = async(logger, apiKey, callIds, method, signal) => {
if (!process.env.HOMER_BASE_URL || !process.env.HOMER_USERNAME || !process.env.HOMER_PASSWORD) {
logger.debug('getHomerPcap: Homer integration not installed');
}
try {
const now = Date.now();
const response = await fetch(`${HOMER_BASE_URL}/api/v3/export/call/messages/pcap`, {
signal,
method: 'POST',
headers: {
'Content-Type': 'application/json',