SwitchPipe: My New Rapid and Easy Way To Deploy Web Apps

It's not very often I get to announce my own work here, but SwitchPipe is a new project I've been working on since my "No True mod_ruby Is Damaging Ruby's Viability On The Web" post. It was Ruby Inside's most commented-on post yet and inspired a lot of discussion about the state of deploying Ruby apps online, and got me to thinking about how to build something to achieve ultra-easy Ruby Web app deployment.

SwitchPipe is a proof of concept Web application process manager and request proxy. Backend Web applications are loaded into their own processes, making SwitchPipe language and framework agnostic. HTTP requests are proxied at the TCP level using information extracted from the HTTP headers to establish which backend application is requested. Unlike dispatch / proxying tools that take a totally different approach (such as the wonderful Swiftiply), SwitchPipe is not designed for raw performance, but ease of use and simplicity. You don't have to think about port numbers (beyond the one that SwitchPipe resides on!), starting or stopping backend apps, and a whole lot of other dull stuff. You can even run a full demo of SwitchPipe once you've checked it out via SVN (or downloaded the tarball) with a single command (it'll even install the dependencies!).

SwitchPipe is not the solution, but it's a solution, and one that is well suited to certain types of environment. I've been running several Rails applications live using SwitchPipe and deploying new versions is as simple as an svn checkout.. no restarts, nothing. Adding a new Rails app (or Merb, or Ramaze, or whatever) to SwitchPipe is a case of uploading, creating a config file, and that's it.. you don't even have to restart SwitchPipe!

It's early days for SwitchPipe, but I'm pretty happy with it just for the major benefits it's provided me in deploying various Ruby-backed Web apps, so hopefully a few other people will find a use for it. If you do, make sure to join its Google Group! And yes, it will also be available via Git soon.

Anon: Sort of, but it does more (which is the reason it exists). It doesn't just load balance and act as a proxy/reverse proxy, but it actually launches and controls the backend applications that serve the requests.

Stephen: One thing you might like is that Thin support is baked in to SwitchPipe, including connecting to Thin via UNIX sockets (a new feature they just added). Of course, SwitchPipe is not a performance demon, but it still makes things a little faster :)

Jonno: I actually pondered (as have a few other people) a "mod_mongrel" a year ago, but none have come to fruition (that I know of). SwitchPipe is, however, reasonably close to it in terms of the goal. The only downside is you have another daemon to keep an eye on and you have to set up some rewrite rules or ProxyReverse directives. An Apache module that automated the Apache end would rock, of course, although I must admit I rather dislike installing them (!!)

Random thing to point out.. JRuby Inside ( http://www.jrubyinside.com/ ) is one of the Rails apps currently deployed on my own SwitchPipe installation. If you're the first visitor in a minute or more, you'll notice the first request takes a few seconds, but from then on, it'll be pretty fast. The reason for that is I have a 60 second timeout (I think.. might be 120 or 180 seconds, I forget) on that app, so it's not taking up memory or resources if no-one's using it.

Yes. The configuration file for an app has a "max_instances" parameter (although I believe the default is 3). So, if requests come through for that app, it will spawn up to that many instances (as necessary), assign them port numbers automatically, and dispatch requests to each of them automatically. You can then change this max_instances setting on the fly if you need more capacity at some point.

SwitchPipe itself is designed in a way that it can deal with multiple concurrent requests at a time without needing multiple instances of itself.

This also makes SwitchPipe ideal for Apache 1.3 setups where mod_proxy_balancer is not available, since mod_proxy (and mod_rewrite) can proxy well to a single port backend. SwitchPipe then handles the clustering automatically.

This looks perfect for what I've been looking for -- for a corporate intranet environment, I've been looking for a way to easily deploy several rails (or othe framework) apps.

What I really want to enable is for non-developers in our engineering community to create simple web apps (used for data mining and reporting mostly). Rails / merb / etc makes some of that easy, but the deployment part of it has been a huge barrier. I'm looking forward to trying this in practice...

Jeremy: And with support for "Host" headers being added in the next minor version (might even do it tonight, for trunk only), it could potentially even be the "front end" daemon too (no Apache, etc, needed). Actually, it can already work as a front end, as long as you don't mind using subdirectories to delimit apps (JBoss style).

Ericson: I guess that's really what it is. It's like a FastCGI that uses HTTP. I would love to hear of any experiences you have, as I have not heard any bad experiences / criticisms yet, and I really would be expecting at least some :)

@Peter: You may have just saved me a chunk of coding. I've been mulling over the design of a very similar process manager/proxy daemon, though I was planning on implementing it as a mod_ruby handler rather than a standalone service.

I may still go that route for performance reasons, as I've started to figure out recently that just how huge the performance hit is up-front for any HTTP proxy-based architecture. Being able to prototype my system with SwitchPipe will help me get a proof-of-concept up sooner, though.

@Lennon: Wow. I can't believe I didn't think of that idea (especially it was the mod_ruby discussion that inspired this). I think it might actually be possible to get SwitchPipe running through mod_ruby in some way, although I haven't got any experience with it directly.

The performance hit isn't /too/ bad with SwitchPipe, as it doesn't do full HTTP parsing, etc (as a regular HTTP proxy would do), but you still have to proxy from Apache -> SwitchPipe so in any case there is still latency. SwitchPipe also supports connecting to backends via UNIX sockets which can speed things up( Thin, a competitor to Mongrel, supports this). For the sort of things I deploy, however, this is more than acceptable for the ease of deployment.

I do think, however, that it should be possible to rig up or adjust SwitchPipe in some way for mod_ruby operation, so if ever anyone does that or has any tips, let me know and we'll get something in there!

This is a very cool idea, I'm excited to try it! I love the fact that you've optimized for ease of use and simplicity.

It's been driving me crazy that there are so many ruby web server projects (seemingly more every week) and they're all trying to compete on performance! I mean come on, with Ruby's notoriously slow performance, is the web server really the bottleneck?!?

Ruby web frameworks have always been more about fast, fun development, not performance. And it looks like you're well on your way to completing the picture by adding fast, fun deployment. Kudo's.

BTW... You mention adding support for host headers... Have you considered hooking up one of the Ruby web servers (like Mongrel) as an optional frontend for switchpipe?