Fix write hang, WebSocket dispatch, dead rockspec URLs - #373
Merged
Conversation
send()/SSL_write() return 0 for an empty buffer, which the write handlers mistook for EWOULDBLOCK and kept retrying instead of completing. For write_zero_copy() this spun the ioloop at 100% CPU forever (e.g. serving a zero-length static file); for the regular write() path the callback just silently never fired. Complete an empty buffer immediately in all four write handlers instead of calling send()/SSL_write() with length 0.
_continue_ws called self:open() with no arguments, so route capture groups never reached user handlers even though every other handler gets them via self._url_args. Guard against a nil _url_args too, for handlers not built through normal Application dispatch. Also implement the big-endian frame length/send functions, which were empty stubs and a hard crash on ppc/s390x hosts. On a BE host wire order already equals host order, so these are the LE versions minus the byte-swap calls.
GitHub disabled the unauthenticated git protocol in 2022, so source.url in these rockspecs is unreachable. Switch to git+https for the specs that aren't frozen historical releases. Also add the new websocket spec to the default Docker test run, it's headless and deterministic like the others already there.
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
write("")) used to never complete:send()/SSL_write()legitimately return 0 for an empty buffer, and the write handlers treated any 0 return as "would block, retry" instead of checking completion first. Forwrite_zero_copy()this spun the ioloop at ~100% CPU forever. Fixed in all four write handlers iniostream.lua.WebSocketHandler:open()never received URL route captures, even though every other handler gets them viaself._url_args. Fixed, with a nil guard for handlers not built through normalApplicationdispatch._frame_len_16,_frame_len_64,_send_frame) was a set of empty stubs, a hard crash on ppc/s390x hosts rather than just a byte-order bug. Implemented (wire order already equals host order on BE, so no byte-swap needed). Not tested on real BE hardware, verified by code reading against RFC 6455 only.git://github.com/..., which GitHub disabled in 2022, breakingluarocks install turboentirely. Fixed for the non-frozen rockspecs (turbo-2.1-4,turbo-dev-1).spec/websocket_spec.luaand a couple of regression tests tospec/iostream_spec.lua, and wired the websocket spec into the default CI run.Closes #332, #328, #268, #340
Test plan
make docker-test(default suite): 72/0make docker-test ARGS="spec/iostream_spec.lua": new tests pass, confirmed they fail withSync wait operation timed outagainst the pre-fix codemake docker-test ARGS="spec/websocket_spec.lua": 3/3StaticFileHandler, 200 response in ~3ms, CPU idle afterward