Yehuda Katz is a member of the Ruby on Rails core team, and lead developer of the Merb project. He is a member of the jQuery Core Team, and a core contributor to DataMapper. He contributes to many open source projects, like Rubinius and Johnson, and works on some he created himself, like Thor.

@alkema You can skip it with Rails 3. You'll just have to manage the dependencies manually. Good luck :)

Archive for October, 2008

Awesome bundling in Merb 1.0 final

Since we released RC1, people have had persistent issues with bundling Merb gems. It turns out that the most common reason, by far, is conflicts between gems bundled in your app with gems available in your system.

When we first set up bundling, we thought it would be convenient to be able to bundle only some of the dependencies for your application. As it turns out, that blunts the reason for bundling in the first place: hassle-free, write-once-run-anywhere applications.

Through the course of four RCs, we’ve tried a number of things, none of which were really effective. The only full solution that guarantees that your bundled app runs correctly on development boxes and production boxes is to bundle everything in your app, and completely ignore your system gem repository.

While it is easy enough to mix and match, the number of reports of failure, combined with failures by the core team itself, leads us to believe that this is a *bad* idea, especially given some of the current assumptions made by Rubygems (which causes it to activate the latest version of a gem, which might conflict with a different dependency).

A simple example of a failure:

  • merb-haml 0.9.12 relies on merb-core 0.9.12
  • Imagine you have merb-core 0.9.13 installed in your system
  • running the merb binary loads the latest merb from all your repositories.
  • this will load merb-core 0.9.13
  • a dependency on merb-haml 0.9.12 will try to activate merb-core 0.9.12, which will conflict with the already loaded 0.9.13.

This is just one example of many issues that people had. The solution is to rely entirely on bundled gems, and remove system gems from bundled binaries.

The side-effect is that you will need to bundle gems like mongrel, rake, etc. But it’s clear to me that even bundling mongrel and rake is a good idea, as different versions of mongrel or rake can have subtle differences that lead to infuriating bugs. I personally have experienced some of these bugs in my day, and being able to package up an entire working app would have been a godsend!

RC5, which should be the final release before 1.0 final is released at RubyConf, will include bundle-everything by default, as well as more support for webrat, JRuby, and Windows.

Thanks!

Share and Enjoy:
  • Digg
  • Reddit
  • HackerNews
  • Twitter

Merb 1.0 RC3 Released!

We released Merb 1.0 RC3 today, inching a bit closer to a 1.0 final, which we intend to release at RubyConf. RC3 is mostly bugfixes, but there are some items of note:

  • Since we intend to support webrat as a primary mode of testing in 1.0 final, we’ve restructured the testing helpers to make that possible. No testing API changes at this time.
  • In 1.0 final, get/post/put/delete will be aliases for request(). At this time, they’re still aliased to the old pre-1.0 request()-helper. To help ease the transition, we will probably provide a use_legacy_request_helper! method.
  • There was a bug in request testing that preventing sessions from persisting for more than 2 requests. We have implemented a cookie jar, so sessions now persist properly (basically, we emulate a real browser).
  • As a result, you can now pass a :jar parameter to request(), which will allow you to test multiple sessions in the same test. If you specify no :jar parameter, all request() operations will use a :default jar. The syntax is request(“/foo”, :jar => :my_jar). request(“/foo”) is the same as request(“/foo”, :jar => :default).
  • merb-action-args works with ParseTree 2.x and 3.x.
  • merb-auth had a few bugs around redirecting back and retrying failed logins that were resolved.
  • The final, good API for dependency is solidified. A few things that you can do now: dependency “parse_tree”, :require_as => “ParseTree” { # do stuff after the gem is loaded }. You can also pass :immediate => true to have the gem load immediately, instead of being deferred until the framework is set up (the default).
  • We should now fully support Windows.
  • Seamless JRuby support is coming via Glassfish. RC3 has some fixes to make it simpler for Glassfish to hook in.
Good night and good luck!
Share and Enjoy:
  • Digg
  • Reddit
  • HackerNews
  • Twitter

Merb Master Process

Apologies for the delay in posting about this. I was enjoying the fantastic Ajax Experience and jQuery Camp out in Boston, where I got a chance to hang with my jQuery compatriots as the huge Microsoft and Nokia announcement broke.

Now that I’m back, I want to talk about the cool new features we’ve been adding to Merb’s server. Let’s take a look at them one at a time:

  • When a Merb server boots up and tries to bind to existing ports, it doesn’t crash. Instead, it waits for each port to become available and binds when they do. As a result, you can start up a new merb, and then gracefully kill the old one. This should make restarting clusters of merbs significantly less painful, and with almost no downtime.
  • Merb’s clusters have been rewritten to take advantage of Ruby Enterprise Edition, which makes it much easier to share memory between workers in a Merb cluster. Using Ruby Enterprise with Merb 1.0 should yield around the same 30% memory improvement that Phusion Passenger yields.
  • Merb clusters are now controlled by a master process, which can be told to gracefully kill all of its children, or reload the application code (but not init.rb or gems). 
  • Sending an INT to the master process (directly or via merb -K all) tells each of the worker processes to gracefully die. 
  • Sending a HUP to the master process tells each of the worker processes to gracefully die, but to start up a new cluster with reloaded code. This bypasses reloading Merb, gems, and init.rb, so the restart is much quicker than doing a full reload. This is also the same internal code used by development mode code-reloading, which has now been made 100% foolproof.
  • Killing a worker process (either via INT, which is graceful, or KILL, which isn’t) will cause a new process to be respawned instantly. We’re talking basically no time at all, since no code needs to be reloaded (the spawner process forks right before binding to a port)

All of these improvements are just harbingers of even more improvements, making Merb’s master process even more powerful and smart.

The most important thing to keep in mind is that Merb has been significantly tuned for Ruby Enterprise, and with regular Ruby, there is a bit of overhead for the master processes. All of the features above will work correctly with standard Ruby, but you’ll get them for free (memory-wise), as well as quite a bit of improved memory overall in a cluster by using Ruby Enterprise.

Please please please check it out.

Share and Enjoy:
  • Digg
  • Reddit
  • HackerNews
  • Twitter