Skip to content
This repository has been archived by the owner on Feb 14, 2018. It is now read-only.

Switch to Puma for web server instead of Thin #331

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kyledrake
Copy link

Sinatra prior to 1.3 uses "EventMachine" mode of Thin, which disables Ruby
threading. This can dramatically decrease throughput on JRuby and
Rubinius, because it cannot take advantage of multiple CPU cores with
this configuration.

In addition, the MRI (Matz Ruby Implementation) C version of Ruby has a
pattern where it will not block on IO if threading is used, because IO
will run in the background concurrently while work is being done on
other threads.

Unfortunately, Thin with Sinatra < 1.3 forcibly turns threading off due
to EventMachine, which makes it so the server has to stop and wait for
external IO requests to finish until it can continue serving content (the
exception being if you use the special EventMachine drivers, which are
very difficult to implement).

Puma does not have these restrictions. It is a fast, clean
implementation based on threads, and should run well on all Ruby
implementations. It should increase throughput dramatically vs Thin for
sites doing a lot of remote IO. It also has a lot of power features like
HTTP Keepalive. And best of all, it removes the EventMachine dependency!

More information is available from their web site: http://puma.io

This is a fairly big change, so it would be great if a few people tested it and gave it a thumbs up before merging. An alternative solution to this would be to upgrade to a Sinatra >= 1.3 and the latest version of Thin, which will automatically use threaded mode by default, but this seemed like the more conservative option of the two. That said, ultimately it might be nice to upgrade to 1.3+ as well.

I deployed to Heroku with this change and it appears to be working just fine!

Sinatra prior to 1.3 uses "EventMachine" mode of Thin, which disables
Ruby
threading. This can dramatically decrease throughput on JRuby and
Rubinius, because it cannot take advantage of multiple CPU cores with
this configuration.

In addition, the MRI (Matz Ruby Implementation) C version of Ruby has a
pattern where it will not block on IO if threading is used, because IO
will run in the background concurrently while work is being done on
other threads.

Unfortunately, Thin with Sinatra < 1.3 forcibly turns threading off due
to EventMachine, which makes it so the server has to stop and wait for
external IO requests to finish until it can continue serving content
(the
exception being if you use the special EventMachine drivers, which are
very difficult to implement).

Puma does not have these restrictions. It is a fast, clean
implementation based on threads, and should run well on all Ruby
implementations. It should increase throughput dramatically vs Thin for
sites doing a lot of remote IO. It also has a lot of power features like
HTTP Keepalive. And best of all, it removes the EventMachine dependency!

More information is available from their web site: http://puma.io
@WardCunningham
Copy link
Owner

Kyle and I have been discussing SFW's complex interaction with Event Machine for some time. I would appreciate other ruby eventing experts giving Puma a try in wiki farm configurations where "recursive" calls still ocurre.

This is the troublesome request:

https://github.com/WardCunningham/Smallest-Federated-Wiki/blob/master/server/sinatra/server.rb#L319

Notice that there are heuristics that try to short-circuit this call when it is clear that the requested content is from the save server. However, these heuristics don't cover every case.

@WardCunningham
Copy link
Owner

@kyledrake I remain interested in this improvement but have other issues sneaking in front of this one.

@andyl
Copy link

andyl commented Apr 1, 2013

Are multi-threaded servers overkill? Jruby / Rubinius dependencies add complexity.

@kyledrake
Copy link
Author

This improvement is good for both MRI and the threaded versions. MRI will be able to do concurrent IO work with this change. This does not affect JRuby/Rubinius compatibility, and I think that should be treated as a separate issue.

Switching to Puma removes the EventMachine dependency (Puma is pure-ruby with a cross-platform C or Java based HTTP parser) which actually reduces the complexity by taking a lot of code out. EventMachine occasionally has compatibility issues too, it didn't work with Ruby 2.0 for a while IIRC.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants