-
Notifications
You must be signed in to change notification settings - Fork 7
Why Fast
Because
Nyara uses two evented parsers:
- http_parser with chunked encoding support
- multipart-parser-c (todo)
And implemented the following in addition:
- RFC2616 compliant
Accept*parser - MIME type matcher
- Url-encoded parser for path / query / request body
To support HTTP methods like PUT, DELETE for archaic browsers, a technique called method override is used, and the HTTP method can be overriden by a request param (usually named _method). In Rack the param may rest in request body, so it needs to parse the whole body before routing to a desired action. In Nyara the param is always in request path query, and routing starts when header completes. So server can do a lot of things before a huge file completely uploaded and provide better user experience.
Nyara is only for systems with kqueue or epoll (maybe iocp in the future). Manufactural event queue is a waste of time.
The common caveats of an evented framework is: mutual callbacks must be used to ensure the order of operations. In eventmachine, sent data buffers are copied and chained in a deque to flush, and close_connection_after_writing must be called to ensure that all data are written before close.
While in Nyara, the data sending is much simpler: we send them directly, if there are remaining bytes, the action fiber is paused. When the socket is ready again, we wake up the fiber to continue the send action. So a lot of duplications, memory copy and schedule are avoided and close is the close.
To make better user experience, you may tune the server to stop GC while doing request, and start GC again after every serveral requests. But by doing so you are increasing the probability of OOM: there are cases when malloc or new fails to get memory while the GC stopped by you can release some. With C-ext this can be partly fixed with Ruby's ALLOC and ALLOC_N, which can make GC release some memory when malloc fails. But with C++ this becomes a bit messy: you need to redefine new operators.
In Nyara, the use of C++ memory allocation is limited to boot time (the use of C++ may possibly removed in the future) so your server has less chance to be quit by a silent OutOfMemoryException.
To prevent session from being compromised, OpenSSL::PKey::DSA.syssign is used to generate session signature. The signature is randomized with complex random number generator, and the cost is constant time (and a bit heavy), while verifying is much faster.
In most requests, you just read things from session, but do not change it at all. So avoiding signing can greatly lower the process time.
There are performance specs on:
- Accept-* parse vs sinatra
- param parse vs CGI.unescape
- param encode vs CGI.escape
- layout rendering vs tilt
See https://github.com/luikore/nyara/blob/master/spec/performance_spec.rb for more details
- Getting started with a single file
- Getting started with a project structure
- Configure options
- Modulize actions with controller
- Routing and path helper
- Action metadata and content format
- Header, param, session and cookie
- Flash
- The request object
- Response helpers
- Render, layout and partial
- View streaming
- Other helpers
- Custom helpers
- Action lifecycle callbacks
- Test helper
Recipes(todo)
- [Web server]
- [Secure headers]
- [Mapping different paths to a same controller]
- [I18n]
- [Form helpers]
- [Oauth]
- [Test]
-- Digging deeper --