As the previous maintainer of Reel ( High-performance Web Server based on Celluloid ) alongside the author of Falcon ( Samuel Williams ) I am proud to see this release get some attention, and heartily congratulate the author on work well done, both in the release itself, and in progress within the Ruby language.
Samuel is one of Ruby's best. He wrote RubyDNS as well, which was one of the best implementations of Celluloid, the asynchrony / concurrency / parallelism / distributed computing library written in Ruby, which has since come to EOL or hit a ceiling as trends shifted.
I am happy to see Samuel ( ioquatix ) continue his momentum personally, and contribute so much.
Yes, I don't know Samuel, but form his blog he has been using Ruby for 10+ years. And he is only been in a more active role in Ruby VM over the past few years.
I think it was his Fibre[1] works that caught my attention.
No idea why it hasn't committed yet.
Congrats for being on Ruby Core, we really need more people to push Ruby forward. And thanks for the work on Fibre and Falcon, I hope I will have time to test it out and see if it could fully replace Nginx + PUMA / Unicorn.
I program almost exclusively in Ruby (because it's the best, right ? :) ) and I'm always happy to see experts like you keep the Ruby flag flying by actively expanding the language.
Yeah one of the first things I do when I want to make a project is google the name to see what is using it already. If its too popular or too close to what I am solving I dont use the name. Reminds me of that WAMP Protocol (which I found a stupid name cause the acronym already says protocol at the last P) which collided with WAMP the Windows Apache MySQL PHP project. The engineer apparently didnt care. I wish engineers would stop to think because poor naming could ruin a project or product.
I always assumed in this case that it was due to Monty Python rather than anything else (I.e. the prevalence of Falcon-name-themed high-performance frameworks is due to Monty Python).
Indeed. Additionally, not take anything away from the Ruby counter part, the Python project is amazing and we use it in production. I really prefer the endpoint and viewmethod declaration methods in Falcon over Flask
# In this example, I use blueprint plugin
@bp.route('/', methods=['PUT'])
def create_resource():
return
vs
class Resource(...):
def on_put(self, request, response):
return
Flask's hooking logic [1] is nice but I much prefer Falcon's middleware logic [2]. This then ties into the fact that Flask's design requires working with `g` [3] (essentially a global object) where as the middleware design leads us to bake in data in the request object. The example blow demonstrates how middleware definition works and how "adding data" per request works in both of these frameworks.
# Flask; assuume `app` exists
from flask import g
@app.before_request
def before_request():
g.some_variable = 'foobar'
vs
class ExampleComponent(object):
def process_request(self, req, resp):
req.some_variable = 'foobar'
Additionally, Falcon middleware API also exposes `process_resource` which is similar to above but also allows us to _pass_ arguments to the routed resource instance.
This sounds great! Are there any things I need to watch out for before switching from Puma to Falcon? And is it production-ready now, or does it still need some time to mature and have feature parity with other web servers?
Would be great to have a comparison with Falcon. Also, speaking of performance, I still need to set up jemalloc. Have heard lots of good things about that.
I really think it depends on your use-case. The surface area of HTTP is huge. I'd like to think it's production ready, but I'm only just beginning to dog-food Falcon in production on my end.
Pragmatically speaking, it will be production ready when it reaches 1.0 - until then, make sure you test it well and keep an eye on how it behaves. I've literally run millions of requests against test servers, but... it's pretty wild out there!
Kudos to this project for having a funding model. At 120USD / year / per production instance many teams could convince management to pay it and help fund the project but also have the maintainers as support staff if needed.
I love stuff like this thanks. It's really interesting to see that Falcon is based on the https://github.com/socketry/async library.
I've previously been looking at https://github.com/ruby-concurrency/concurrent-ruby based on its use in Rails and was wondering if there's a comparison of the two approaches anywhere that would be newbie friendly?
I was also wondering will Falcon run on JRuby? (I see that nio4r does so hopefully that also means that things like Async-Container will.)
I've been doing my best to try and support JRuby but in actual fact, JRuby simply isn't that compatible with MRI where it matters. I hope we can fix this but honestly I can only do so much. I tend to focus my efforts on MRI since that's what I use day-to-day.
I was just about a month ago trying to figure out if Rails and HTTP/2 could work together; and it seems this is about the only answer out there currently (or did I miss one?)
First, thank you! It looks like really solid work.
This project must be fairly new as I was not able to find it mentioned and compared with other ruby servers. Does anyone know some comparison running puma vs falcon or passenger vs falcon?
Would be interesting to chat more about this - would like to learn more about how the request queuing works (that was where we ran into problems with puma). My email is in profile
ioquatix, just I'm clear, if this is an evented server it will use just one core? Or does it create one process per core? If not do you recommend we use https://github.com/stripe/einhorn to split the work across N falcon processes (one for each core)?
And do you have advice / recommendations on database pool sizes when using Rails? I assume that each process will have access to as many connections as specified in the DB_POOL config? Does falcon need any pre/post fork re-creation of all connections?
Someone more knowledgeable about Rails can pitch in, but I believe in the absence of any connection management code, Rails will check out one connection per request the first time it is used? And checkin after the request terminates? If that is the case, wouldn't the number of simultaneous requests effectively be capped at the database pool size for DB heavy applications?
This is controllable, but by default it makes one process per core.
Regarding the pool size, I'd suggest that it should correspond more to how many simultaneous connections you think you'd have per process, so maybe just choose something like 32 to start with? Benchmarks would be required to find the sweet spot.
There is more than 9000 bird species and yet we have two web frameworks with the same name.
Naming projects proves the-letter-agencies theory that people passwords are chose from very limited word space :) (https://falconframework.org) was there already.
This is unfortunate, but at the time I only checked RubyGems.org and didn't think to check another language or package repository. So, I apologies, but there was no bad intentions, perhaps just a little bit of bad luck and ignorance.
That being said, it's actually named after the Peregrine Falcon, which is the fastest bird in the animal kingdom, and it was a friendly poke at Puma :)
WEBrick was ruby’s standard library httpd back in the day... I remember it being mostly unusable in production for different reasons. But every now and then a new httpd would appear: mongrel, unicorn, passenger, puma, etc…
Sometimes the new implementation was not only “faster” under certain benchmarks, but deemed superior for “philosophical” reasons… I think it was the case for unicorn that load balanced over a pool of unix processes.
Eventually I left the ruby/rails world behind. Not the main reason, but I remember performance problems being very frustrating.
To quote [an old, 2011 blog post from] antirez: “it is not ok that by default [ruby] is so damn slow”. [1]
I was expecting to find ruby state of affairs to be the same these days, but looking at TechEmpower’s recent benchmarks [2] (benchmark reading caveats apply), seems like ruby implementations are reasonably speedy nowadays: benchmarks reflect results within the same order of magnitude to the fastest ones, except for the plaintext benchamark. I extracted some interesting metrics below.
Still, Ruby consistently comes after the 100th entry for all benchmarks.
A lot of people will say that the reasons to use ruby are the gains in productivity and the expresibility, DSL capabilities, etc. If that’s the evaluation metric, maybe Clojure could be a good alternative. Also, it performs very well! (thanks to the JVM, no doutbts). I believe immutable by default is a better way to build apps, and in Clojure, the whole language is built around this concept. Ruby is the other way around: even parts of the language that shouldn't are open for modification!
I wonder if jRuby would be a good contender for performance.... but...
* I’m not sure why there are no jRuby implementations on the techempower benchmarks.. evidently, not a very popular technology?
* I’m guessing that startup time for tools like IRB must the one of the turnoffs for ruby people.
The tech empower benchmarks for Ruby are a bit foobar, I tried to fix it but ran out of time. I wouldn't trust it completely. I'm not saying it's wrong, I just don't think it's the complete picture.
Samuel is one of Ruby's best. He wrote RubyDNS as well, which was one of the best implementations of Celluloid, the asynchrony / concurrency / parallelism / distributed computing library written in Ruby, which has since come to EOL or hit a ceiling as trends shifted.
I am happy to see Samuel ( ioquatix ) continue his momentum personally, and contribute so much.