Tuesday, July 11, 2006

Erlang + Yaws vs. Ruby on Rails

Ruby on Rails is great. It makes web development easy, fun and productive. The MVC separation between layers is well thought out and the Ruby language, although painfully slow is quite suitable for quick projects that emphasize developer productivity over raw performance.

Although I love Ruby on Rails, I just keep gravitating back to Erlang, even when I just want to do a quick and dirty project. In most people's minds, 'Erlang' isn't the first association when they think of web development, but Erlang, in combination with Yaws, gives you a very nice web development package. Admittedly, Erlang doesn't have the whole gamut of web-specific APIs that Ruby + Rails have, but Erlang does carry its weight in all letters of the MVC. For the Model, forget database abstraction layers: you have a pure Erlang distributed database called Mnesia. For the view, Yaws has ehtml. For the controller, Yaws has appmods and Erlang's pattern matching.

I'm not going to delve into all the differences between the two solutions, because there are many advantages and disadvatages to both, but I will say that, holy crap, Erlang + Yaws is so much easier to setup and install than Ruby + Gems + Rails + FastCGI + Lighttpd + MySQL + MySQL bindings + every-other-package-in-the-universe. I've been slaving away at these installation instructions for OS X for what feels like an eternity, and my patience is running very low.

If you want to create a full dynamic, database driven, insanely scalable webapp with Erlang, all you have to do is install Erlang, install Yaws, configure Yaws to serve your application's directory, and you're done. You don't even have to worry about setting up a database engine: just call the Mnesia functions. You want to create a new database? Call mnesia:create_schema. To start a new Mnesia session, call mnesia:start. And if you want clustering for you database, it's built in. Just start an Erlang node on another machine, call mnesia:add_table_copy with the table and node's names.

Mnesia is not perfect, of course, and its biggest downside at the moment is that its disc storage engine isn't suited for storing large volumes of data (Mnesia was designed for soft real-time applications where the data is stored mostly in RAM), but I hope this will be resolved in the not-too-distant future.

(Update: if you look at Ulf Wiger's comment, you will see that Mnesia disc storage does scale up to many GB, which is more than enough for most websites. There are a couple of other issues with Mnesia disc storage to be aware of, though. They are discussed here.)

The View component is worth discussing a bit more. For the views, Ruby has ERb, which allows you to embed Ruby in HTML. Yaws takes a totally different, and in some ways much more elegant approach: ehtml. ehtml is a set of simple conventions for describing dynamically generated HTML using Erlang tuples, which Yaws translates into the output sent to the browser. With ehtml, you never have to step out of Erlang (of course, you can if you want to). If you want to see an example of this, look at this shopping cart code.

There's a lot more to say about this topic and I'll probably blog about this more in the future. For now, I hope I have given you something interesting to digest. If you want more food for thought you can check out some of my previous postings on this topic.

Help spread the word: digg digg this posting

27 comments:

Roberto said...

Hi Yariv, ever thought of putting this great blog story on digg.com ? Then maybe one day there are more then the two of us doing webapps in Erlang ...

regards
Roberto

yariv said...

Hehe, that's an interesting idea. Maybe I'll do that. Erlang + Yaws do need some new blood. Let's see if digg can help spread the word.

yariv said...

It's submitted. Let's see how the crowds react :)

Jason Hoffman said...

Nice series of erlang articles.

Yes, erlang is great. I have been a fan and used it for years, and everything that we don't do in ruby nowadays, we do in erlang. We primarily use erlang (and increasingly more with yaws) for "infrastructure" items (we have some shots of erlang based load balancers and schedulers up).

We're also the "official" rails host, host the ruby on rails project (host half of wordpress.com too), and some of the core rails team are on staff.

It'll be interesting to see how erlang comes along, and keep up articles on it (I'll be bookmarking the site).

Ulf Wiger said...

Nice post. I would perhaps qualify the remarks about mnesia as "isn't suited for storing very large volumes of data" - as in many gigabytes. I know that commercial DBMSs can, and frequently do, handle huge amounts of data. But most websites will not need that much. In http://www.erlang.org/ml-archive/erlang-questions/200511/msg00118.html, I wrote about storing 3.2 GB in one disk-based mnesia table on a 64-bit machine, and inserting 5 million records in one table. Performance was quite good, so I'd say mnesia's storage capacity is more than enough for a large number of web apps. And if this won't do, well you can keep your data in Oracle, Sybase, MySQL or whatever, and still keep the logic in Erlang + Yaws.

BTW, I ran 20 million simultaneous erlang processes without performance degradation on that same machine. Try that in Ruby. ;-)

yariv said...

Ulf, thanks for the feedback. I updated the posting by your input.

There are still the issues with the freelist and the repair time, though, and if you use and external DBMS you lose the elegance and developer productivity of Mnesia. In addition, setting up clustering with other DBMS's is either impossible or just a big pain. I wanted to show that Erlang web development can be easy and elegant, and that amazing scalability can be attained with relatively little effort. Using MySQL, Postgres, etc. from Erlang isn't as beautiful as Mnesia.

Roberto said...

dugg it !

shadytrees said...

"ehtml is a set of simple conventions for describing dynamically generated HTML using Erlang tuples, which Yaws translates into the output sent to the browser. With ehtml, you never have to step out of Erlang (of course, you can if you want to)."

Regarding ehtml, you may find the cgi module[1] for Ruby useful as it has a similar syntax. I think Ruby on Rails allows it; it's just using Ruby closures like ehtml uses Erlang tuples.

[1]: http://ruby-doc.org/docs/ProgrammingRuby/html/web.html

Duke Ionescu said...

Links! If your intended purpose is to popularize Erlang + Yaws (watch out, you spelled it Erland in one instance!), it would help if you provided links to these technologies, like you do for the competition (RoR). Now that you're of reddit fame, I'm willing to gamble that there are many visitors that don't know _anything_ about Erlang, much less Yaws (you can count me amongst the latter). While everybody knows how to use Google, why not provide a few quality links, such as erlang.org, while at it? BTB, this page is #2 on Google for "Erlang Yaws" -- good work!

anonymous said...

There are many much better ways to set up RoR such as http://blog.evanweaver.com/articles/2006/06/26/building-ruby-rails-lighttpd-mysql-and-postgres-on-os-x-tiger

The hive logic article is out of date.

Joe Pecoraro said...

I went to the link which shows that Ruby is the one of the slowest languages. I played around with it a little bit and check this out!

If all you do is change the settings for gzip bytes to 5 then Ruby turned out as the BEST language.

I don't quite know what that means, but I think its worth mentioning!

Yariv said...

Joe, according to the website, to derive "gzip bytes" they "started with the source-code markup you can see, removed comments, removed duplicate whitespace characters, and then applied minimum GZip compression." If I understand correctly, this means that gzip bytes shifts the weight towards languages whose benchmarks require relatively little code. This indicates that Ruby is expressive and productive, but it doesn't contradict its slowness.

Yariv said...

Thanks for the tips, Duke. I fixed the typo :) Lets hope non-Erlangers would find my "Hitchhiker's Guide to Erlang" posting.

Austin Ziegler said...

Yariv, I would strongly suggest not using the Alioth shootout as a basis for anything. Most of the folks who use and follow Ruby know that the Alioth shootout is one of the least useful sites on the entire Internet, mostly because of the sloppy (and ultimately dishonest) way that the shootout is run. It's presented, on its front page, as entirely serious and encouragement is given to people to improve the algorithmic implementation for their language, but no controls are done. There's one example where the Python language version uses some settings which allow it to run *at all*; similar settings are available for Ruby programs, but must be set at the user's shell [ulimit]. They do not do this and report that the Ruby program doesn't run. The same algorithmic test has three different Perl versions, one of which takes advantages of particular Cperl implementation factors that may not apply in a different implementation. Ruby performs slower than many languages, but it may perform fast *enough* for your needs, or it might not. But the shootout is a useless waste of time that no one should bother using. Ever.

Rickard said...

The slowness of Ruby isn't contested by anyone who knows better--it's just a fact. There is work being done on speeding it up on multiple fronts.

Yariv said...

Hi Austin, Rickard. I'm actually one of the people who doesn't care that much about Ruby's speed. I would use whatever language makes me most productive, even at the cost of running an extra server or two. This is why I've been blogging about Ruby/Rails and Erlang as opposed to, say, Java and OCaml.
Although I don't contest Rails's high developer productivity, I still think that Erlang makes me, at least, more productive, even without all the libraries that Rails has and which lack from Yaws.

dennis said...

Regarding mnesia scaling...if you were to cluster servers, would it scale up nicely with that 3.2GB per server? If so, it might not be bad for a web-based discussion forum...Now if only there were an RSS/Atom library...

Yariv said...

Hi Dennis,

I'm pretty sure Mnesia could handle 3.2GB without too much difficulty. I haven't deployed large scale backends with Mnesia, though, so I can't be sure. I suggest you ask on the erlang-questions list.

Porting Ruby's Feedparser library into Erlang shouldn't be too hard :)

Yariv

albertlee said...

sounds great

a-nonymzen said...

There was a question from Demius regarding yaws and oracle. wouldn't it be possible to use odbc? I spotted this url: http://erlang.org/doc/doc-5.5/lib/odbc-2.0.6/doc/html/index.html

Mat Schaffer said...

You might want to add a link for 'configure Yaws to serve your application’s directory'. You're the top hit if I google for 'Yaws configure' :)

richard said...

missing from the discussion is how to configure lighttpd so that it can send requests to yaws... much the way fcgi or scgi would.

José Manuel Peña said...

Hey Yariv! What if you mix up erlang Mnesia database with ruby on rails thorugh an MQ server as rabbitmq?

You're not going to take advantage of YAWLS server, but at least you can still using Mnesia. However, this means that you have to do your application asyncrounous friendly.

I think this solution is as scalable as flexible. Gaining all RubyOnRails features.

Yariv said...

I think using Mnesia with Rails is like going to a fancy restaurant and ordering a cheeseburger.

Nick said...

Yariv, why do you think that mixing HTML and code in ehtml is a good idea? It goes very much against the MVC paradigm. Plus, do you really want to tell me that you like escaping HTML attribute values.

pedz said...

Have you looked at the JavascriptMCV framework? The Controller, View, Model are (kinda) in the user's browser. This makes the web site more and more just a data store and it puts as much work as possible in the user's browser (distributed out to the client) rather than on the server.

I've not used it yet but it seems, over time, this will be the way to go.

Ankit Singh said...

Hi Yariv,
Nice article. But I like to tell you one thing that Mnesia support disc-only-copy. The only problem with mnesia when storing large Number of data. This problem we also solved by Table fragmentation. We will create another table after certain number of entries done like 1000 or 2000 +. So. I think LEMYA framework (a slang I call for LINUX, Erlang, Mnesia And Yaws) will be more used world wide in future. off- course there is lot of improvement we to do. But seriously, this framework is too lite & fast.