Open
Description
actions/cache#1217 attempted to work around a dangling socket, which became especially apparent when that action migrated to Node 20, as Node v20 started keeping connection alive by default.
This solution worked for actions/cache in the meantime, but caused downstream consumers of to implement the same logic to avoid hanging processes and generated similar issues, such as:
- @actions/ccache causing 2min slowdown with Node 20 runtime #1643
- Fix performance regression masci/datadog#33
The leaked socket originates in cache/src/internal/cacheHttpClient:
const uploadChunkResponse = await retryHttpClientResponse(
`uploadChunk (start: ${start}, end: ${end})`,
async () =>
httpClient.sendStream(
'PATCH',
resourceUrl,
openStream(),
additionalHeaders
)
)
sendStream return a response, the body of must be consumed to avoid holding the event loop open.
Something like the following ought to do it:
const uploadChunkResponse = await retryHttpClientResponse(
`uploadChunk (start: ${start}, end: ${end})`,
async () => {
const response = await httpClient.sendStream(
'PATCH',
resourceUrl,
openStream(),
additionalHeaders
)
await response.readBody()
return response
}
)