feat(start): take --keepAliveTimeout, as next start does
Summary
upwind's native server keeps Node.js's keep-alive default, as next start does. It closes an idle connection about 6 s after its last answer (a keepAliveTimeout of 5 s plus Node.js's 1 s buffer). A client that sends on a pooled connection just as the server closes it gets ECONNRESET. In deploy-tests on node (run 41382774099, shard 48/64), Playwright's API request on a prefetch in vary-params-base-dynamic failed this way.
This PR adds an option and leaves the default alone:
upwind starttakes--keepAliveTimeout <ms>, spelled likenext start --keepAliveTimeout: a whole number of milliseconds from 1 to 2147482647. Node.js arms an idle socket's timer at the timeout plus its 1 s buffer, so a longer value would overflow its timers. At 2147483647, every answer warned (TimeoutOverflowWarning) and the timer was clamped.- The CLI hands it to the server as
UPWIND_NODE_KEEP_ALIVE_TIMEOUT.server.mjsalso reads that variable when it is run directly, as it readsPORTand the otherUPWIND_NODE_*variables. - When the option is unset, nothing changes.
- deploy-tests starts the
nodetarget's server with 10 minutes. That is longer than any suite leaves a connection idle, and its clients do not resend when a pooled connection is reset. - The README describes the option, and when to set it above a proxy's idle timeout.
The same race inside the runtime's native bridge is fixed separately in #432.
Verification
- A
next-formfixture was built fornodewith this branch and served withupwind start.- Without the option, answers carried
Keep-Alive: timeout=5, and a request 7 s after the previous one needed a new connection. - With
--keepAliveTimeout 65000, answers carriedKeep-Alive: timeout=65, and the same request reused the connection.
- Without the option, answers carried
- Unit tests cover:
- the flag and its refusals, 2147482648 among them;
- the environment variable, the process's taking precedence over a file's, and the flag over both;
- the server's own parser.
- On Node.js 24.22.1, a server with a keep-alive timeout of 2147483647 warned on its answer, and one with 2147482647 did not.
- The adapter's
native-listeningtests, the upwind CLI project (415 tests) and the deploy-tests unit tests (186) pass. Typecheck, lint, format, knip and vocabulary pass.
Summary by cubic
Adds --keepAliveTimeout <ms> to upwind start, spelled and validated like next start's. It sets how long the server keeps an idle connection open after its last answer; unset, Node.js's default stands (about 6 seconds).
A client that sends on a pooled connection just as the server closes it gets ECONNRESET, which happened in a deploy-test on node. The CLI hands the value to the server as UPWIND_NODE_KEEP_ALIVE_TIMEOUT, which server.mjs also reads when run directly. deploy-tests now starts the node target's server with 10 minutes so suites' pooled clients avoid that race.
Details
- The flag and the variable accept a whole number from 1 to 2147482647 ms; the flag wins over the process's variable, which wins over an env file's.
- The top is one second below Node's timer limit, because Node adds its 1 s keep-alive buffer to the timeout.
--keepAliveTimeoutis documented in the README, including setting it above a proxy's idle timeout.
Summary by CodeRabbit
- New Features
- Configure the native Node.js server’s idle connection timeout with
--keepAliveTimeout <ms>orUPWIND_NODE_KEEP_ALIVE_TIMEOUT. - The timeout accepts whole-number values from 1 to 2,147,483,647 milliseconds. A command-line value takes precedence over the environment setting; when neither is set, Node.js uses its default.
- Configure the native Node.js server’s idle connection timeout with
- Documentation
- Added guidance on setting the timeout and its effect on idle connections.