fix(http): server.ref()/unref() return this instead of a raw number (#5011)#5023
Merged
Conversation
added 2 commits
June 12, 2026 13:10
…#5011) `server.ref()`/`server.unref()` on a node:http/node:https server returned the receiver handle as a raw number instead of the server object. Node returns `this`, so `http.createServer(cb).unref().listen(...)` broke under Perry with `TypeError: (number).listen is not a function`. Root cause: native_table/http_server.rs had no ref/unref rows for the HttpServer/HttpsServer class filters, so the calls fell through to a generic handler that yielded the handle as a number — the same shape `listen` had before #2129. - Add ref/unref NativeModSig rows (ret: NR_PTR) for both server tables. - New js_node_http(s)_server_ref/_unref runtime fns return the receiver handle and toggle a new `refed` flag on HttpServer; server_is_active now ignores a listening-but-unref'd server so the loop can exit (Node semantics), while pending listen callbacks / queued requests still keep it alive to flush in-flight work. - Mirror the methods in the `server: any` dynamic dispatcher and register the externs in ext_registry, stdlib_ffi, and force_link_http_server. - Add ref/unref manifest rows + regen docs. Verified: typeof s.unref() === "object", s.unref() === s, s.ref() === s, createServer(cb).unref().listen(...) works, and a listening unref'd server exits cleanly (exit 0, no hang).
…part2.rs (2000-line cap)
b5b746e to
bdd7e95
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #5011 —
server.ref()andserver.unref()on anode:http/node:httpsserver returned the receiver handle as a raw number instead of the server object. Node returnsthis, sohttp.createServer(cb).unref().listen(...)broke under Perry withTypeError: (number).listen is not a function(test-http-request-method-delete-payload.jsand friends).Root cause
crates/perry-codegen/src/lower_call/native_table/http_server.rshad entries forlisten/close/closeAllConnections/… but none forref/unref, so they fell through to a generic handler that returned the handle as a number — the exact shapelistenhad before #2129.Fix
ref/unrefNativeModSigrows (ret: NR_PTR) for both theHttpServerandHttpsServerclass filters.js_node_http_server_ref/_unrefandjs_node_https_server_ref/_unrefreturn the receiver handle (sos.ref() === s) and toggle a newrefedflag onHttpServer.server_is_activenow ignores a listening-but-unref()ed server, so the event loop can exit while the server is still bound (Node semantics) — pending listen callbacks and queued requests still keep the loop alive long enough to flush in-flight work.ref/unrefin theserver: anydispatcher (handle_dispatch.rs).ext_registry.rs,runtime_decls/stdlib_ffi.rs, and theforce_link_http_serveranchor table; addedref/unrefmanifest rows and regenerateddocs/src/api/reference.md.Acceptance — verified locally
typeof s.unref()→object,s.unref() === s→trues.ref() === s→truecreateServer(cb).unref().listen(...)works (listening on number)cargo test -p perry-api-manifest→ 32 + 4 passed, 0 failed (manifest/docs drift clean)Repro added at
test-files/test_http_server_unref_5011.ts.Not in scope
Separate
(number).<method>cases tracked under #4975:new http.Agent().createConnection(...)returning a number (test-http-socket-encoding-error) andserver.ALPNProtocolsnot being a Buffer (test-https-argument-of-creating).