Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement an incremental HTTP parser using the llhttp APIs #90

Closed
5 tasks done
rdw-software opened this issue Aug 6, 2022 · 3 comments · Fixed by #167
Closed
5 tasks done

Implement an incremental HTTP parser using the llhttp APIs #90

rdw-software opened this issue Aug 6, 2022 · 3 comments · Fixed by #167

Comments

@rdw-software
Copy link
Member

rdw-software commented Aug 6, 2022

Goals:

  • Can generate HTTP messages from llhttp callbacks without invoking C-to-Lua callbacks (which are extremely slow)
  • The FFI layer's performance should be at least 80% (in the average case) of the raw llhttp performance
  • Parsed messages that are too large to be buffered should trigger llhttp errors and not SEGFAULT or overwrite memory
  • LuaJIT string buffers can optionally be used to store large body payloads (to faciliate streaming to temporary files, later)
  • Buffered requests should be small enough to fit into common CPU caches (approximated by the 1k requirement for my i7)
@rdw-software
Copy link
Member Author

rdw-software commented Dec 10, 2022

I'm not 100% on the requirements here, since most special/fringe cases are either handled by llhttp itself, or would need to be tested separately as part of #137 (and related issues). I suppose as long as "chunks" can be parsed and (llhttp-ffi) events are triggered on success/error, that's as good a starting point as any.

The main thing I've taken care of already is to allow forwarding events to Lua from C without incurring the 50x slowdown. Right now, the parser can replay events and generate (buffered) Lua requests/responses at about 40%+ native performance, which could clearly be better but also a lot worse. If more is needed, 60% to 95% should be possible by moving the HttpMessage generation to C as well, though it would require putting hardcoded limits on various things (and increase the risk of segfaults).

Streaming mode is TBD, but should be possible via libuv APIs already (need to overwrite the parser's default event handlers).

@rdw-software
Copy link
Member Author

rdw-software commented Dec 24, 2022

The above design is still too slow. The last version amounted to about 16-20% of llhttp's performance. Considering there are many features that were missing, I might just go a different route and assemble the messages fully in C. This means:

  • Hardcoded size limits have to be used (via compile-time defines), to avoid lots of allocations
  • The limit can't be changed at runtime :( Unless string buffers can be woven in again, somehow
  • Streaming large messages will need a completely different design, and probably a new API
  • Extra features may also need to be (at least partially) added in C, which could be annoying if they're complex
  • On the plus side, the performance is basically 95-100% at all times so that concern is eliminated...

I guess the Lua version that's based on string buffers could be used for the streaming mode. If there's so much I/O then the parsing overhead should be negligible, i.e. the slowdown doesn't matter as much. There may still be issues with the excessive memory consumption in those cases, though. Perhaps the best solution is no solution and to just use nginx if this feature is needed?

@rdw-software
Copy link
Member Author

The current version should fulfill all requirements and allow future extension, for example streaming large files via libuv FS requests.

I'm sure a lot could be done to improve the implementation, but I guess it's good enough to move on to the HTTP RFCs for now.

@rdw-software rdw-software changed the title Add an incremental HTTP parser using the llhttp APIs Implement an incremental HTTP parser using the llhttp APIs Dec 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment