First off, we wanted to clear up the issue of the name - the website of the project is modrails.com, but the name Phusion Passenger is used as well. Ninh Bui explains:
Phusion is the name of our company whereas Phusion Passenger is the official name for mod_rails. Most people from the community probably have a good notion of what a mod_rails should be from the mod_* naming convention, so we've kept this alias for this purpose.
Even though we initially planned on going for mod_rails alone, the Ruby on Rails core team and we thought that 'Passenger' fitted better within the Rails paradigm. In particular, the experience that Phusion Passenger (aka mod_rails) strives to deliver is pretty much the same as that of a (train) passenger: just sit down and enjoy the ride ;-) .
Another point is the license or conditions under which Phusion Passenger is distributed:
As for the license, we've indeed made it GPLv2 with an additional clause that people often tend to misinterpret and we'd like to take this opportunity to address this 'issue' en masse: instead of limiting the license, we've actually allowed for the community to do more with the source!We were also interested to see how Phusion Passenger stacks up against similar solutions for Rails deployment:
Also, we have had a lot of experience working in the open source community, and we have grown very attached to it. We believe that the open source development model, in conjunction with the driving force of a commercial company, allows us to deliver higher quality products. In other words, we believe that this is the best way for a commercial institution to give back to the community.
As an example of this, Phusion Passenger has been designed and written to be reliable and robust in production environments. Nevertheless, some may still experience deployment problems, or need a custom feature. We are providing paid commercial support for those who need it. Our team of experts are experienced in a wide variety of environments — Linux-based environments in particular — and have deep knowledge of the Ruby internals, Ruby on Rails and Passenger.
Unlike Swiftiply, Mongrel Cluster, etc. Phusion Passenger's application pool is managed automatically based on the current traffic. Also, crashed Rails applications are restarted automatically. This means that no configuration or process monitoring is required, and this should result in lower system administration overhead. There's a variety of configuration options available, and they are documented in the users guide.
We were interested to learn what's necessary to deploy and redeploy a Rails application with Phusion Passenger:
Two minutes of your time depending on your internet connection ;-) . All kidding aside though, updating and redeploying your Rails application using Phusion Passenger, would only require you to re-upload your application and touch the restart.txt file. And that's pretty much it. The latter step is required if you don't want to restart Apache (and we think most of you want this ;-)).
On a technical note, the latter step updates the timestamp of the restart.txt file, on which Phusion Passenger will determine whether or not to restart the Rails application.
Rails deployment isn't the only problem Phusion's developers are trying to address. One issue with hosting many Rails processes is the memory overhead. Every Ruby process needs to load Ruby and Rails libraries into memory - since these are distinct processes, none of this is shared right now (Ruby code is store on the heap, so unlike shared libraries, it's not shared among processes).
One of Phusion's developers, Hongli Lai tried to use the Unix syscall
fork()
to allow sharing of data among Ruby processes. The idea is to get a Ruby process with the libraries set up - and then fork()
the process to get another one. Calling fork()
in a process, basically duplicates this process in an efficient way. The two processes basically look the same, including the same data in their address spaces. However - this is not Shared Memory - instead the Virtual Memory systems of OSes use a method called Copy On Write (COW) to allow the processes to see the same data but also modify their own private copy. As long as the data is only read, only one copy of the data needs to be around - however, once one process starts to modify the data, the data's copied over to this process. Obviously - sharing read only data, such as library code or similar, is possible with this. However - there is a problem with languages that use Garbage Collection: a full Garbage Collection walks the heap and marks all reachable objects. The important word here is "mark" - a flag on the object is flipped. If any of these objects are shared with another process (from a
fork()
), COW kicks in and copies the data over - which means the data isn't shared anymore, and every process has it's own copy. Hongli Lai's solution to this problem is to make the Ruby Garbage Collector COW-friendly, i.e. so a collection won't cause the data to be copied. Ninh gives some more details on the state of this work and how it relates to Phusion's products:
The copy-on-write garbage collector is as good as finished. We're currently polishing the release and writing the website. Also, we're working on a scientific paper on this with the help of ir. Hans Scholten of the University of Twente. One can expect a release within the next few weeks. We understand that people may not like the idea of patching Ruby, so we've put extra effort into ensuring that installation is as easy as possible, and that the installation is completely self-contained so that no system files are touched.
We are going to release this work as "Ruby Enterprise Edition" (and yes, we're well aware of its name, but allow us to elaborate on this at Railsconf ;-) ). Please bare with us in the meantime, as we assure you, it's going to be worth it ;-) ). It should also be noted that Ruby Enterprise Edition is fully backwards compatible with standard Ruby (1.8).
If Phusion Passenger is instructed to use Ruby Enterprise Edition, then Passenger will automatically make use of copy-on-write semantics. This results in large memory savings in Rails applications. In fact, early tests have indicated that this is about 33% in an average case.
The critical reader will note that Ruby Enterprise Edition does all this in a transparent manner, but also offers the application programmer to toggle the GC optimization on and off during runtime. It is for this reason that Ruby Enterprise Edition should be considered as a superset of Ruby.
For this, we had to change the way the Ruby heap is implemented. It now uses a set of marking bitfields instead of mark bits inside objects. Performance is variable and depends on the application and the workload. On some Rails apps we've measured a performance hit of 5%. On others, 20%. On yet others, 0%, i.e. no performance hit. We'll elaborate on this at Railsconf for those who want more information on this, or possibly sooner if our schedule would allow for it.
For everyone interested in trying out Phusion Passenger, the Phusion website features a screencast with the necessary steps, or simply check out the installation instructions for Phusion Passenger. As Phusion Passenger is an Open Source project, you can look at GitHub repository of Phusion Passenger.