0.0
No commit activity in last 3 years
No release in over 3 years
An experimental web server using modern Linux kernel features.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.7
~> 10.0

Runtime

 Project Readme

Butterflies

Butterflies is an experimental web server for Ruby applications that takes advantage of modern Linux kernel (version 3.14+) features and threads.

Design

Butterflies is inspired by the Erlang HTTP web server Cowboy. While we can't emulate everything Cowboy does in Ruby, due to the differences between Ruby and Erlang, we can borrow a little bit from Cowboy's design.

Cowboy works by spawning a listening socket and then sharing that socket with a pool (potentially thousands of acceptors) of Erlang processes that accept on the socket. Erlang's unit of concurrency is known as a process. Erlang processes spawn very quickly so this model works well. In Ruby we have threads for concurrency, which unfortunately don't spawn that fast. It is best to spawn the threads you need upfront and re-use them.

The two premier Ruby web servers today, Unicorn and Puma, work in very interesting and different ways. Unicorn is a lot like Cowboy in that it shares a listening socket among many child processes that then accept on this socket. The problem is that Unicorn's processes are operating processes which consume a lot more memory than a Thread or an Erlang process. This also means one process is only ever handling one request at a time. The advantage of this approach is that the kernel of the underlying operating system load balances requests for you.

Puma works by using threads for handling requests. Puma manages this by having a thread listen for new connections and then pushing the connections onto a queue. There is then a pool of threads that monitor and handle requests. Puma also has a Reactor where you can check-in long lived connections.This is ideal because regardless of the runtime you're using you can serve more than one request in parallel per operating system process. The disadvantage is that you have only one acceptor and have to manage the log of waiting connections instead of letting the operating systen kernel do this for you.

Like Puma, Butterflies is designed using threads. Butterflies takes advantage of the SO_REUSEPORT socket option that is available in Linux kernel version 3.9+ and BSD operating systems. Each Butterflies thread can listen and accept connections on the same port. The back log of connections will be load balanced by the underlying kernel so you get performance and reliability without having to manage that complexity yourself. You get the simplicity of Unicorn with the parallel request handling of Puma!

Installation

Add this line to your application's Gemfile:

gem 'butterflies'

And then execute:

$ bundle

Or install it yourself as:

$ gem install butterflies

Usage

This gem is not ready to be used yet.

TODO

  • epoll FFI binding for Ruby or just use nio4r
  • TCP_FASTOPEN (Linux kernel 3.7+)
  • TCP_AUTOCORKING (Linux kernel 3.14+)

Contributing

  1. Fork it ( https://github.com/[my-github-username]/butterflies/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request