Skip to content
Zete Lui edited this page Jul 14, 2013 · 4 revisions

Because

Solid http parsers written in C

Nyara uses two evented parsers:

And implemented the following in addition:

  • RFC2616 compliant Accept* parser
  • MIME type matcher
  • Url-encoded parser for path / query / request body

Decisive routing on header complete

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.

Thin evented IO layer built for BSD or Linux

Nyara is only for systems with kqueue or epoll (maybe iocp in the future). Manufactural event queue is a waste of time.

Solve sequential problems with Fiber

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.

More stable memory management

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.

Avoid signing session for every request

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

Clone this wiki locally