<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>jkraemer.net - Blog</title>
  <id>tag:www.jkraemer.net,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://www.jkraemer.net/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.jkraemer.net/" rel="alternate" type="text/html"/>
  <updated>2008-06-25T08:53:22Z</updated>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-06-25:276</id>
    <published>2008-06-25T08:24:00Z</published>
    <updated>2008-06-25T08:53:22Z</updated>
    <category term="nginx"/>
    <category term="performance"/>
    <category term="plugin"/>
    <category term="rails"/>
    <category term="session"/>
    <category term="webit"/>
    <link href="http://www.jkraemer.net/2008/6/25/get-a-new-bike-powered-by-rails" rel="alternate" type="text/html"/>
    <title>Get a new bike, powered by Rails</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.fahrrad-xxl.de/&quot;&gt;&lt;img src=&quot;/assets/2008/6/25/fxxl_small.jpg&quot; /&gt;&lt;/a&gt;
Working with &lt;a href=&quot;http://www.webit.de/&quot;&gt;webit!&lt;/a&gt; I recently built the dynamic parts of the &lt;a href=&quot;http://www.fahrrad-xxl.de/&quot;&gt;new website of Fahrrad-XXL&lt;/a&gt;, a quite large group of bike dealers here in Germany. Besides the product catalog, which is maintained via a separate Rails app, there&#8217;s also lots of static content which is managed with the help of &lt;a href=&quot;http://www.bricolage.cc/&quot;&gt;Bricolage&lt;/a&gt;, a Perl CMS generating static html pages.&lt;/p&gt;

&lt;p&gt;I originally intended to name this post &lt;em&gt;Find a new bike, powered by Ferret&lt;/em&gt;, because the full text search is one of the coolest features of the site. But maybe I&#8217;m a bit biased here ;-). In fact, I&#8217;ll delay the Ferret stuff to a later post and instead tell you about another interesting aspect of this project.&lt;/p&gt;

&lt;h3&gt;Integration of CMS driven static html with Rails&lt;/h3&gt;

&lt;p&gt;As long as the static pages are &lt;em&gt;completely&lt;/em&gt; static that&#8217;s no big deal and we already did that in other projects: just have the CMS generate your Rails layouts to ensure visual consistency across the site, and let it publish it&#8217;s files into &lt;code&gt;public/&lt;/code&gt;. But what do you do if your static pages aren&#8217;t really &lt;em&gt;that&lt;/em&gt; static?&lt;/p&gt;

&lt;p&gt;At &lt;a href=&quot;http://www.fahrrad-xxl.de/&quot;&gt;www.fahrrad-xxl.de&lt;/a&gt; you have a watch list where you can remember bikes you want to revisit later on. The number of bikes currently on this list is shown on every page, regardless of whether it stems from the CMS or comes out of the Rails application.&lt;/p&gt;

&lt;p&gt;So how can you do this? The first solution that comes to mind is of course to embed some ERb rendering the watch list status, and pipe each and every page through Rails. This might have worked but why take on the whole overhead of Rails compared to serving the file directly through the web server just for that tiny little number?&lt;/p&gt;

&lt;p&gt;I wanted to do better, and remembered a &lt;a href=&quot;http://blog.kovyrin.net/2007/08/05/using-nginx-ssi-and-memcache-to-make-your-web-applications-faster/&quot;&gt;blog post talking about nginx server side includes&lt;/a&gt; I stumbled across a while ago. The SSI feature of &lt;a href=&quot;http://nginx.net/&quot;&gt;nginx&lt;/a&gt; is really cool because it allows you to include dynamically generated content retrieved via HTTP somewhere in your page.&lt;/p&gt;

&lt;p&gt;So what we did was building an action that just rendered that tiny snippet showing the status of your watch list, and put an SSI include directive pointing to this action on every page:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2008/6/25/ssi.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Before serving such a page to the user, nginx will parse the page for any SSI directives, retrieve the content from the location specified there, and replace each directive with the content:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2008/6/25/cart.jpg&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;The good&lt;/h3&gt;

&lt;p&gt;So what have we gained? It&#8217;s still one request to the rails application per page, but it&#8217;s one that&#8217;s substantially faster because it only needs to output a few bytes of text instead of the whole page.&lt;/p&gt;

&lt;p&gt;In fact we started using nginx&#8217; SSI in several other places, too, which yielded another benefit of this approach: with pages containing multiple SSI directives you will experience multiple concurrent requests hitting the Rails app, which is a good thing because by splitting the task of rendering a page into several smaller tasks these may be distributed across multiple CPU cores and/or physical servers.&lt;/p&gt;

&lt;p&gt;Having pages composed of multiple small snippets also eases caching: the decision whether a particular piece of content is eligible for caching and when it has to be expired is far easier to make for a small and focused snippet, than for a whole page potentially containing data with different life cycles. For example in our case we could easily page cache the watch list status snippet and expire it once the user modifies his watch list. Or, even better, use memcached to store the rendered snippet and have nginx retrieve it directly from there as shown in the blog post I mentioned above.&lt;/p&gt;

&lt;h3&gt;The ugly&lt;/h3&gt;

&lt;p&gt;There are some things you should be aware of when trying this approach out:&lt;/p&gt;

&lt;h4&gt;No setting of cookies&lt;/h4&gt;

&lt;p&gt;Your actions rendering stuff included via SSI cannot set cookies because the response you send is received by nginx, and not by the client. And since it wouldn&#8217;t make any sense for nginx to try and merge headers from multiple SSI responses into the single response that gets sent back to the client, it silently drops all those headers. So, no cookies, and especially no modification of session data if you use the cookie based session store. Which leads us to the next point:&lt;/p&gt;

&lt;h4&gt;Don&#8217;t use Rails&#8217; stock session stores&lt;/h4&gt;

&lt;p&gt;At least if you intend to have multiple SSI-directives on a single page and the corresponding actions are session-aware (i.e. you don&#8217;t call &lt;code&gt;session :off&lt;/code&gt; for them). After processing a request Rails by default writes back the session data to the configured session store, even if you didn&#8217;t touch the session at all. That doesn&#8217;t hurt much as long as you don&#8217;t have concurrent requests for the same session, or none of those requests modifies the session state. &lt;/p&gt;

&lt;p&gt;With nginx and SSI you &lt;em&gt;will&lt;/em&gt; have concurrent requests for the same session, so now if at least one of these requests changes session data, there&#8217;s a good chance it won&#8217;t end up stored correctly just because another request finished a bit later, overwriting the updated session data with stale data read from the session store before the change has been saved by the first request. Fun stuff, cost me a day to debug ;-)&lt;/p&gt;

&lt;p&gt;To get around this issue we&#8217;re using the &lt;a href=&quot;http://svn1.hosted-projects.com/fcheung/smart_session_store/trunk&quot;&gt;SmartSessionStore plugin&lt;/a&gt;. You can find out more about the issue and the plugin in this &lt;a href=&quot;http://www.texperts.com/2007/05/01/race-conditions-in-rails-sessions-and-how-to-fix-them/&quot;&gt;fine blog post&lt;/a&gt; at texperts.com.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-05-17:272</id>
    <published>2008-05-17T13:46:00Z</published>
    <updated>2008-06-24T19:56:47Z</updated>
    <category term="ferret"/>
    <category term="git"/>
    <link href="http://www.jkraemer.net/2008/5/17/acts_as_ferret-moved-to-git" rel="alternate" type="text/html"/>
    <title>Acts_as_ferret moved to Git</title>
<content type="html">
            &lt;p&gt;I&#8217;ve been using git-svn for a while now with nearly all my svn-based projects, so this was a logical step when &lt;a href=&quot;http://www.rubyforge.org&quot;&gt;Rubyforge&lt;/a&gt; started offering git hosting a while ago.&lt;/p&gt;

&lt;p&gt;So now you can use&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;git clone git://rubyforge.org/actsasferret.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to get your local copy of acts_as_ferret.&lt;/p&gt;

&lt;p&gt;I plan to keep the svn repository&#8217;s trunk in sync with the master branch, so svn users aren&#8217;t left out in the cold.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-04-07:269</id>
    <published>2008-04-07T07:39:00Z</published>
    <updated>2008-04-07T07:40:45Z</updated>
    <category term="jruby"/>
    <category term="rails"/>
    <category term="webit"/>
    <link href="http://www.jkraemer.net/2008/4/7/saxon-government-s-press-releases-now-powered-by-jruby-on-rails" rel="alternate" type="text/html"/>
    <title>Saxon government's press releases now powered by JRuby on Rails</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.medienservice.sachsen.de/&quot;&gt;&lt;img src=&quot;http://www.jkraemer.net/assets/2008/4/7/medienservice_sachsen_small.jpg&quot; alt=&quot;Medienservice Sachsen&quot; /&gt;&lt;/a&gt;
Last week, the &lt;a href=&quot;http://www.medienservice.sachsen.de/&quot;&gt;Medienservice&lt;/a&gt;, the platform via which the saxon government publishes its press releases to journalists and to the public, has been relaunched. It now runs on a cluster of JBoss servers that are part of the official saxon e-government platform. While the public web frontend might look like just another Blog-like application to you, I assure you that the stuff that happens in the background is anything but simple - there&#8217;s a lot of stuff going on like deferred publishing, publishing press releases only to subscribed journalists, and sending out press releases in four different formats including PDF and XML, to only name a few.&lt;/p&gt;

&lt;p&gt;As far as I know this is the first public german JRuby on Rails application - one more reason for me to be proud of being part of the team at &lt;a href=&quot;http://www.webit.de/&quot;&gt;webit!&lt;/a&gt; that built this baby.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-02-26:268</id>
    <published>2008-02-26T21:01:00Z</published>
    <updated>2008-02-26T21:30:11Z</updated>
    <category term="ferret"/>
    <category term="rdig"/>
    <category term="ruby"/>
    <link href="http://www.jkraemer.net/2008/2/26/rdig-0-3-5" rel="alternate" type="text/html"/>
    <title>RDig 0.3.5</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;/projects/rdig&quot;&gt;RDig&lt;/a&gt; is a tiny web and file system crawler built on top of the &lt;a href=&quot;http://ferret.davebalmain.com/&quot;&gt;Ferret&lt;/a&gt; search engine. It&#8217;s one of my less active side projects and from what I can tell doesn&#8217;t have a very large user base. However there are some people out there who actually use it, and some of those people even tell me so and suggest new features from time to time :-)&lt;/p&gt;

&lt;h3&gt;Limit crawling depth&lt;/h3&gt;

&lt;p&gt;You can now configure a maximum crawling depth to restrict RDig to only index pages up to this level. For example, setting &lt;code&gt;config.crawler.max_depth = 1&lt;/code&gt; will make RDig only index the configured start pages, and pages the start pages directly link to. You get the picture I guess.&lt;/p&gt;

&lt;p&gt;This option is especially useful if restricting RDig to a pre-defined number of hosts is not an option for your use case, but you still don&#8217;t intend to have it crawl the whole web.&lt;/p&gt;

&lt;h3&gt;HTTP proxy auth support&lt;/h3&gt;

&lt;p&gt;If you are behind a proxy and have to use HTTP Basic Authentication with it to get through, you can specify proxy url, user name and password:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;cfg.crawler.http_proxy = &quot;http://yourproxy:8080&quot;
cfg.crawler.http_proxy_user = &quot;username&quot;
cfg.crawler.http_proxy_pass = &quot;secret&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Under the hood&lt;/h3&gt;

&lt;p&gt;I put some work into refactoring parts of RDig in order to make integration with &lt;a href=&quot;/projects/acts_as_ferret&quot;&gt;acts_as_ferret&lt;/a&gt; easier. I&#8217;ll write more about that in another post.&lt;/p&gt;

&lt;h3&gt;Get it!&lt;/h3&gt;

&lt;p&gt;RDig is available as a gem via &lt;a href=&quot;http://rubyforge.org/projects/rdig/&quot;&gt;Rubyforge&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-01-27:266</id>
    <published>2008-01-27T10:00:00Z</published>
    <updated>2008-01-27T10:08:34Z</updated>
    <category term="ruby"/>
    <link href="http://www.jkraemer.net/2008/1/27/regexps-on-steroids-with-ruby-1-8-x" rel="alternate" type="text/html"/>
    <title>Regexps on steroids with Ruby 1.8.x</title>
<content type="html">
            &lt;p&gt;Ruby 1.9 comes with a new powerful regular expression engine called &lt;a href=&quot;http://www.geocities.jp/kosako3/oniguruma/&quot;&gt;&lt;em&gt;Oniguruma&lt;/em&gt;&lt;/a&gt;. It sports better handling of UTF8 encoded content, plus goodies like positive and negative look-behind or named matches. Here&#8217;s a &lt;a href=&quot;http://www.siaris.net/index.cgi/Programming/LanguageBits/Ruby/Oniguruma.rdoc&quot;&gt;good overview&lt;/a&gt; about these and some more of the new features of Oniguruma.&lt;/p&gt;

&lt;p&gt;There are two ways to get Oniguruma into a pre-1.9 Ruby: You can patch the Ruby source tree with Oniguruma and build your own Ruby, or use the &lt;a href=&quot;http://oniguruma.rubyforge.org/&quot;&gt;Oniguruma gem&lt;/a&gt;, which makes it fairly easy to use the new style regular expressions in any Ruby 1.8.x project. Here&#8217;s how:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;$ wget http://www.geocities.jp/kosako3/oniguruma/archive/onig-4.7.1.tar.gz
$ tar xzf onig-4.7.1.tar.gz
$ cd onig-4.7.1
$ ./configure --prefix=/usr
$ make
$ sudo make install
$ sudo gem install oniguruma
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;prefix&lt;/code&gt; argument in the call to &lt;code&gt;configure&lt;/code&gt; - it should point to the location of your current ruby installation. So if your ruby executable is located in &lt;code&gt;/usr/bin&lt;/code&gt;, you&#8217;ll have to use &lt;code&gt;/usr&lt;/code&gt; here as shown above.&lt;/p&gt;

&lt;p&gt;If everything went well so far, try it out in irb:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require 'rubygems'
require 'oniguruma'
reg = Oniguruma::ORegexp.new '(?&amp;lt;before&gt;.*)(a)(?&amp;lt;after&gt;.*)'
match = reg.match( 'terraforming' )
puts match[0]         &amp;lt;= 'terraforming'
puts match[:before]   &amp;lt;= 'terr'
puts match[:after]    &amp;lt;= 'forming'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The downside of not having Oniguruma patched into a self-compiled version of Ruby is that something like &lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;'terraforming' =~ /(?&amp;lt;before&gt;.&lt;em&gt;)(a)(?&amp;lt;after&gt;.&lt;/em&gt;)/
&lt;/code&gt;&lt;/pre&gt;
won&#8217;t work because it will be handled by your Ruby version&#8217;s built in regexp rengine.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-01-24:265</id>
    <published>2008-01-24T22:34:00Z</published>
    <updated>2008-01-24T22:52:59Z</updated>
    <category term="encryption"/>
    <category term="linux"/>
    <category term="luks"/>
    <category term="security"/>
    <category term="ubuntu"/>
    <link href="http://www.jkraemer.net/2008/1/24/encrypted-root-and-swap-with-suspend-to-disk-on-ubuntu-7-10" rel="alternate" type="text/html"/>
    <title>Encrypted root and swap plus suspend to disk with Gutsy</title>
<summary type="html">&lt;p&gt;In order to give my trusted T42 a slight speed up I decided to replace the built-in 5400rpm hdd with something faster. I decided to go with Seagate&#8217;s ST910021A which seems to be a great choice from what I can tell so far - it&#8217;s noticeably faster and despite it&#8217;s 7200 rpm it&#8217;s nearly as quiet as the original 80GB disk from Hitachi.&lt;/p&gt;

&lt;p&gt;But I digress. Initially I just wanted to copy over all the stuff and be done with it, but then I took the chance to do a fresh install of Ubuntu so I could try out the hard disk encryption setup that has been introduced in the alternate installer of 7.10. Until then I only had an encrypted &lt;code&gt;/home&lt;/code&gt;, which was pretty useless since most of the time my notebook isn&#8217;t shut down but hibernated, and I never needed to type in my passphrase upon resume&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;In order to give my trusted T42 a slight speed up I decided to replace the built-in 5400rpm hdd with something faster. I decided to go with Seagate&#8217;s ST910021A which seems to be a great choice from what I can tell so far - it&#8217;s noticeably faster and despite it&#8217;s 7200 rpm it&#8217;s nearly as quiet as the original 80GB disk from Hitachi.&lt;/p&gt;

&lt;p&gt;But I digress. Initially I just wanted to copy over all the stuff and be done with it, but then I took the chance to do a fresh install of Ubuntu so I could try out the hard disk encryption setup that has been introduced in the alternate installer of 7.10. Until then I only had an encrypted &lt;code&gt;/home&lt;/code&gt;, which was pretty useless since most of the time my notebook isn&#8217;t shut down but hibernated, and I never needed to type in my passphrase upon resume&#8230;&lt;/p&gt;
&lt;p&gt;In order to give my trusted T42 a slight speed up I decided to replace the built-in 5400rpm hdd with something faster. I decided to go with Seagate&#8217;s ST910021A which seems to be a great choice from what I can tell so far - it&#8217;s noticeably faster and despite it&#8217;s 7200 rpm it&#8217;s nearly as quiet as the original 80GB disk from Hitachi.&lt;/p&gt;

&lt;p&gt;But I digress. Initially I just wanted to copy over all the stuff and be done with it, but then I took the chance to do a fresh install of Ubuntu so I could try out the hard disk encryption setup that has been introduced in the alternate installer of 7.10. Until then I only had an encrypted &lt;code&gt;/home&lt;/code&gt;, which was pretty useless since most of the time my notebook isn&#8217;t shut down but hibernated, and I never needed to type in my passphrase upon resume&#8230;&lt;a&gt;&amp;nbsp;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installation of Gutsy, including the setup of encrypted partitions for root, swap and home went without problems, however on first boot I only got a blank screen, and no prompt for a passphrase as I expected. Removing the &lt;code&gt;quiet splash&lt;/code&gt; options from the kernel boot arguments in Grub solved that one, so I could finally see when to enter the pass phrase.&lt;/p&gt;

&lt;p&gt;Not nice, however, that I had to enter it three times now, once for each partition. Maybe I should have guessed this would be the case when the installer also asked me three times, once for each partition&#8230;&lt;/p&gt;

&lt;p&gt;Seems you can get around this by choosing one of the LVM-based encryption options in the installer, which will set up your partitions inside a single encrypted LVM volume. But I didn&#8217;t feel the need for another layer of abstraction between my data and the disk, plus those options all sounded like they would use the whole disk, blowing any existing partitions away. So I decided to fix this on my own.&lt;/p&gt;

&lt;p&gt;A bit of googling quickly led me to the &lt;a href=&quot;https://help.ubuntu.com/community/EncryptedFilesystemHowto5&quot;&gt;EncryptedFilesystemHowto5&lt;/a&gt;, which suggests creating a separate encrypted partition where all the keys for the other encrypted partitions will be stored. That way, you only need to type your passphrase once when the &lt;code&gt;keys&lt;/code&gt; partition is mounted in order to retrieve the (unencrypted) keys for the other partitions from there. The following steps and the initrd script are roughly based on this howto, however the process is much easier since we&#8217;re already starting with a fully encrypted system and only add the additional comfort of that separate keys partition to it.&lt;/p&gt;

&lt;p&gt;So here&#8217;s, in short, what I did, starting from the encryption setup already created by the alternate installer:&lt;/p&gt;

&lt;h3&gt;Make backups&lt;/h3&gt;

&lt;p&gt;I did all this on a fresh install having all my data on the other hard disk lying on the table so there wasn&#8217;t much to backup but I thought I&#8217;d mention it anyway ;-)&lt;/p&gt;

&lt;h3&gt;Set up the keys partition&lt;/h3&gt;

&lt;p&gt;First create a small partition to hold your keys if you didn&#8217;t already do so during installation. Let&#8217;s say this is &lt;code&gt;/dev/sda6&lt;/code&gt;. Then set this up as an encrypted volume and mount it somewhere (you need to be root for all of the following commands):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;/sbin/badblocks -c 10240 -s -w -t random -v /dev/sda6
dd if=/dev/urandom of=/dev/sda6
cryptsetup --verify-passphrase --verbose --hash=sha256 --cipher=aes-cbc-essiv:sha256 \
   --key-size=256 luksFormat /dev/sda6
cryptsetup luksOpen /dev/sda6 cryptokeys
mke2fs -j -O dir_index,filetype,sparse_super /dev/mapper/cryptokeys
tune2fs -c 0 -i 0 /dev/mapper/cryptokeys
mkdir /mnt/cryptokeys
mount -t ext3 /dev/mapper/cryptokeys /mnt/cryptokeys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will check the partition for bad blocks, overwrite it with pseudo-random data, setup a luks volume on it, create a filesystem there and finally mount this at &lt;code&gt;/mnt/cryptokeys&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, create the keys for your root, swap and any other partitions you might have. The fine thing about luks is that you can have any number of keys for a given encrypted volume, so this is pretty straight forward (do the first two lines for root, swap and any other encrypted partitions):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;dd if=/dev/random of=/mnt/cryptokeys/sda7-key bs=1 count=256
cryptsetup luksAddKey /dev/sda7 /mnt/cryptokeys/sda7-key
chmod 600 /mnt/cryptokeys/*-key
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you should ever happen to lose the keys stored on that partition, you will still be able to access your data with the passphrase you told the alternate installer during installation.&lt;/p&gt;

&lt;h3&gt;Create a new initial ramdisk&lt;/h3&gt;

&lt;p&gt;Of course the original initrd image doesn&#8217;t know anything about our new keys partition. To change this we create a &lt;a href=&quot;https://www.jkraemer.net/assets/2008/1/24/cryptokeys&quot;&gt;custom script&lt;/a&gt; named &lt;code&gt;/etc/initramfs-tools/scripts/local-top/cryptokeys&lt;/code&gt; which will mount the keys partition asking for the passphrase, then unlock all other encrypted partitions and finally close the keys partition again. As a bonus, it also tries to resume from the swap partition after unlocking it.&lt;/p&gt;

&lt;p&gt;The script assumes your swap is at &lt;code&gt;/dev/sda8&lt;/code&gt;, and root and home are &lt;code&gt;sda7&lt;/code&gt; and &lt;code&gt;sda9&lt;/code&gt;. Be sure to edit this to suit your needs.&lt;/p&gt;

&lt;p&gt;Before creating the new initrd it&#8217;s a good idea to backup the original one in /boot/, just in case we messed something up. You might even want to create a separate boot menu entry using this original initrd in &lt;code&gt;/boot/grub/menu.lst&lt;/code&gt; below the &lt;code&gt;END DEBIAN AUTOMAGIC KERNELS LIST&lt;/code&gt; line:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;title           Ubuntu 7.10, kernel 2.6.22-14-generic (old initrd)
root            (hd0,4)
kernel          /vmlinuz-2.6.22-14-generic root=/dev/mapper/sda7_crypt ro 
initrd          /initrd.img-2.6.22-14-generic.safe
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To finally create a new initrd, call:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;update-initramfs -u ALL
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Try it out&lt;/h3&gt;

&lt;p&gt;Well, reboot and see if it works :-)&lt;/p&gt;

&lt;p&gt;You should get asked once for your passphrase, and then see the other partitions being unlocked automatically. Thanks to the call to &lt;code&gt;/bin/resume&lt;/code&gt; in the &lt;code&gt;cryptokeys&lt;/code&gt; script resuming from suspend to disk should work, too (which it didn&#8217;t with the setup created by the alternate installer).&lt;/p&gt;

&lt;p&gt;Please let me know if you spot any bugs or have any other comments/thoughts on this.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-01-14:259</id>
    <published>2008-01-14T22:02:00Z</published>
    <updated>2008-01-14T14:48:26Z</updated>
    <category term="grails"/>
    <category term="j2ee"/>
    <category term="jruby"/>
    <category term="rails"/>
    <link href="http://www.jkraemer.net/2008/1/14/grails-project-begging-for-attention" rel="alternate" type="text/html"/>
    <title>Grails project begging for attention</title>
<content type="html">
            &lt;p&gt;Sorry, but I can&#8217;t think of any other reason why Graeme Rocher might write &lt;a href=&quot;http://graemerocher.blogspot.com/2008/01/grails-making-java-developers-forget.html&quot;&gt;such crap&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Among the points he makes when trying to convince his readers why they should choose Grails over Rails, there are at most two or three which are somewhat reasonable, namely those dealing with integrating your application with external J2EE based services. I completely agree that these are valid points when comparing Grails running inside a fully-fledged J2EE container to Rails running in, say, Mongrel. But since Rails runs fine in a J2EE environment as well, that&#8217;s an unfair and misleading comparison.&lt;/p&gt;

&lt;p&gt;Using container-managed database connections via JNDI in a JRuby on Rails web app is no problem at all, neither is &lt;a href=&quot;http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails&quot;&gt;using Quartz to schedule Rails background jobs&lt;/a&gt;, just to name a few examples. I don&#8217;t see anything stopping people from using the whole range of J2EE container features in their JRuby/Rails applications once they need to do so.&lt;/p&gt;

&lt;p&gt;The whole &#8216;Grails is more enterprisey than Rails&#8217; argumentation falls apart once you stop comparing apples to oranges, and slap JRuby + Rails onto that damn app server.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Grails 1.0 coming out within the month&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Uh cool, yeah. Until now I thought statements like this were more a specialty of closed source vendors trying to convince their potential clients not to check out the competition. Looks like they can&#8217;t wait to finally attach that decision maker friendly 1.0 label to Grails ;-)&lt;/p&gt;

&lt;p&gt;Anyway, I feel we&#8217;re all going to have an interesting time in the future watching how the competition between JRuby/Rails and Groovy/Grails goes on. After all, competition tends to lead to better products in the end.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-01-12:258</id>
    <published>2008-01-12T09:21:00Z</published>
    <updated>2008-01-12T09:31:51Z</updated>
    <category term="jruby"/>
    <category term="quartz"/>
    <category term="rails"/>
    <link href="http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails" rel="alternate" type="text/html"/>
    <title>Job scheduling with JRuby and Rails</title>
<content type="html">
            &lt;p&gt;As &lt;a href=&quot;http://www.jkraemer.net/2007/10/31/how-i-learned-to-stop-worrying-and-love-jruby-on-rails&quot;&gt;promised earlier&lt;/a&gt;, here&#8217;s the first of several articles I&#8217;m planning to write about running &lt;a href=&quot;http://www.rubyonrails.org/&quot;&gt;Rails&lt;/a&gt; on &lt;a href=&quot;http://jruby.org/&quot;&gt;JRuby&lt;/a&gt;. Originially I wanted to start this little series with some kind of &#8216;getting started with JRuby on Rails&#8217; guide. Since I didn&#8217;t find the time (or, say, motivation) to write one for weeks now, I decided to skip right through to some more advanced topics. So for this post, I&#8217;m assuming you already got your &lt;em&gt;hello world&lt;/em&gt; JRuby on Rails project up and running and deployed to the application server of your choice. If this is not the case, have a look in the &lt;a href=&quot;http://wiki.jruby.org/&quot;&gt;Wiki&lt;/a&gt; for documentation about getting started. It&#8217;s also worth following &lt;a href=&quot;http://headius.blogspot.com/&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;http://blog.nicksieger.com/&quot;&gt;various&lt;/a&gt; &lt;a href=&quot;http://ola-bini.blogspot.com/&quot;&gt;relevant&lt;/a&gt; &lt;a href=&quot;http://www.bloglines.com/blog/ThomasEEnebo&quot;&gt;blogs&lt;/a&gt;, as well as the jruby and jruby-extras mailing lists.&lt;/p&gt;

&lt;p&gt;Ok, this post is titled &lt;em&gt;Job scheduling with JRuby and Rails&lt;/em&gt; for a reason, so let&#8217;s get started with this now.&lt;/p&gt;

&lt;p&gt;While Rails itself nowadays runs quite flawless inside application servers like JBoss or Glassfish, the usual way to handle background job (push it to some external daemon) doesn&#8217;t fit a J2EE application server environment particularly well. Besides the fact that I couldn&#8217;t think of an easy way to get &lt;a href=&quot;http://backgroundrb.rubyforge.org/&quot;&gt;BackgrounDrb&lt;/a&gt; running from my application&#8217;s WAR file, it simply doesn&#8217;t feel right to have any extra daemons like BackgrounDRb running besides that fat application server.&lt;/p&gt;

&lt;p&gt;As it turns out, there are several ways to do better.&lt;/p&gt;

&lt;h3&gt;The GoldSpike solution&lt;/h3&gt;

&lt;p&gt;The kind folks from the jruby-extras team provide two servlets, &lt;code&gt;RailsTaskServlet&lt;/code&gt;, and &lt;code&gt;RailsPeriodicalTaskServlet&lt;/code&gt; as part of the &lt;a href=&quot;http://wiki.jruby.org/wiki/Goldspike&quot;&gt;GoldSpike&lt;/a&gt; plugin. These servlets can be used to run arbitrary Ruby code inside the context of your Rails application either once or periodically every &lt;code&gt;n&lt;/code&gt; seconds. To schedule a job running &lt;code&gt;YourJobClass.do_stuff&lt;/code&gt; every minute, you would place the following declaration into your &lt;code&gt;web.xml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;servlet&amp;gt;
  &amp;lt;servlet-name&amp;gt;periodicalTask&amp;lt;/servlet-name&amp;gt;
  &amp;lt;servlet-class&amp;gt;org.jruby.webapp.RailsPeriodicalTaskServlet&amp;lt;/servlet-class&amp;gt;
  &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
  &amp;lt;init-param&amp;gt;
    &amp;lt;param-name&amp;gt;interval&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;60&amp;lt;/param-value&amp;gt;
    &amp;lt;param-name&amp;gt;script&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;YourJobClass.do_stuff&amp;lt;/param-value&amp;gt;
  &amp;lt;/init-param&amp;gt;
&amp;lt;/servlet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh the joy of XML configuration files ;-)&lt;/p&gt;

&lt;p&gt;While this works great, I had to run a job not every some seconds, but once a week on a defined day and time. Besides that, declaring a separate servlet for each single background job seems like overkill. Back from my Java days I knew that the &lt;a href=&quot;http://www.opensymphony.com/quartz/&quot;&gt;Quartz&lt;/a&gt; library provided exactly what I needed - support for &lt;a href=&quot;http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html&quot;&gt;cron patterns&lt;/a&gt;. So the challenge was to get Quartz run my Ruby script inside the context of my application.&lt;/p&gt;

&lt;h3&gt;The rails_quartz plugin&lt;/h3&gt;

&lt;p&gt;Our target platform was JBoss, which already includes the Quartz library. I&#8217;m not sure about other app servers, if yours doesn&#8217;t have this already, just &lt;a href=&quot;http://www.opensymphony.com/quartz/download.action&quot;&gt;download quartz&lt;/a&gt; and put the jar including any dependencies somewhere in your application so it ends up inside the &lt;code&gt;WEB-INF/lib&lt;/code&gt; folder of your WAR file. With &lt;a href=&quot;http://blog.nicksieger.com/articles/2007/09/04/warbler-a-little-birdie-to-introduce-your-rails-app-to-java&quot;&gt;Warbler&lt;/a&gt;, which is my preferred way to package JRuby on Rails applications, &lt;code&gt;RAILS_ROOT/lib&lt;/code&gt; is good place, since it will pick up any jars from there automatically.&lt;/p&gt;

&lt;h4&gt;How does it work?&lt;/h4&gt;

&lt;p&gt;The plugin provides a &lt;code&gt;ContextListener&lt;/code&gt;, which, when declared in &lt;code&gt;web.xml&lt;/code&gt;, looks for any job declarations and tells the Quartz Scheduler about them. Here&#8217;s an example &lt;code&gt;web.xml&lt;/code&gt; snippet scheduling a job to run every friday at 10 am:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;context-param&amp;gt;
  &amp;lt;param-name&amp;gt;yourJobCommand&amp;lt;/param-name&amp;gt;
  &amp;lt;param-value&amp;gt;YourJobClass.do_stuff&amp;lt;/param-value&amp;gt;
&amp;lt;/context-param&amp;gt;
&amp;lt;context-param&amp;gt;
  &amp;lt;param-name&amp;gt;yourJobCronPattern&amp;lt;/param-name&amp;gt;
  &amp;lt;param-value&amp;gt;0 0 10 ? * 6&amp;lt;/param-value&amp;gt;
&amp;lt;/context-param&amp;gt;

&amp;lt;listener&amp;gt;
  &amp;lt;listener-class&amp;gt;org.jruby.webapp.quartz.QuartzContextListener&amp;lt;/listener-class&amp;gt;
&amp;lt;/listener&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you see, I use context parameters to configure the command to run, and the cron pattern to use. You can declare any number of jobs you want, just stick to the naming scheme for the parameters: &lt;code&gt;&amp;lt;jobName&amp;gt;Command&lt;/code&gt; and &lt;code&gt;&amp;lt;jobName&amp;gt;CronPattern&lt;/code&gt; so the listener can find out which pattern belongs to which job.&lt;/p&gt;

&lt;p&gt;You can get the plugin here: &lt;a href=&quot;https://projects.jkraemer.net/svn/plugins/jruby/quartz_rails/&quot;&gt;https://projects.jkraemer.net/svn/plugins/jruby/quartz_rails/&lt;/a&gt; . As always, any feedback is welcome.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2008-01-07:257</id>
    <published>2008-01-07T13:50:00Z</published>
    <updated>2008-01-07T13:56:20Z</updated>
    <category term="mongrel"/>
    <category term="rails"/>
    <link href="http://www.jkraemer.net/2008/1/7/strange-mongrel-1-1-error-solved" rel="alternate" type="text/html"/>
    <title>Strange Mongrel 1.1 error (solved)</title>
<content type="html">
            &lt;p&gt;Right after updating Mongrel, gem_plugin and some other (probably unrelated) gems today, Mongrel didn&#8217;t like me any more, refusing to start up any Rail
s application. Instead, I got this nice message complaining about a missing &lt;code&gt;init.rb&lt;/code&gt; in the activerdf gem:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;** Rails loaded.
** Loading any Rails specific GemPlugins
Exiting
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in 'gem_original_require': no such file to load -- /usr/lib/ruby/gems/1.8/gems/activerdf-1.6.1/lib/activerdf/init.rb (MissingSourceFile)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It took me a while to find the &lt;a href=&quot;http://rubyforge.org/tracker/index.php?func=detail&amp;amp;amp;aid=16145&amp;amp;amp;group_id=1306&amp;amp;amp;atid=5145&quot;&gt;fix on rubyforge&lt;/a&gt;  via google, so maybe this helps somebody else having the same problem.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2007-11-18:249</id>
    <published>2007-11-18T16:14:00Z</published>
    <updated>2007-11-18T18:04:55Z</updated>
    <category term="ferret"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://www.jkraemer.net/2007/11/18/acts_as_ferret-0-4-3" rel="alternate" type="text/html"/>
    <title>acts_as_ferret 0.4.3</title>
<content type="html">
            &lt;p&gt;Long time since the last release (not counting the short-lived 0.4.2 &#8230;), and I guess most people already use trunk anyway, but for the faint of heart, here&#8217;s the new &lt;em&gt;stable&lt;/em&gt; version of your favourite Rails fulltext search plugin.&lt;/p&gt;

&lt;p&gt;As always, get it via svn from &lt;code&gt;svn://projects.jkraemer.net/acts_as_ferret/tags/stable/acts_as_ferret&lt;/code&gt;. More installation information can be found on the &lt;a href=&quot;http://projects.jkraemer.net/acts_as_ferret/&quot;&gt;acts_as_ferret Trac site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;No big news feature-wise, I already wrote about the more important features when I added them to trunk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jkraemer.net/2007/8/27/pagination-goodness&quot;&gt;First class pagination support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jkraemer.net/2007/9/2/faster-indexing-with-acts_as_ferret&quot;&gt;Batch indexing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jkraemer.net/2007/10/21/keep-an-eye-on-acts_as_ferret-s-drb-server-with-monit&quot;&gt;Monit sample config for the DRb server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Going through the &lt;a href=&quot;http://projects.jkraemer.net/acts_as_ferret/timeline&quot;&gt;timeline&lt;/a&gt; looking for some cool feature I didn&#8217;t already write about I found several smaller things worth mentioning:&lt;/p&gt;

&lt;h3&gt;Dynamic document specific boosts&lt;/h3&gt;

&lt;p&gt;This comes in handy if you want to have search results automatically ranked by a criteria which is different for each record, e.g. the popularity of an article in your shop:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
class Article
  acts_as_ferret :boost =&gt; :popularity
  def popularity
    # return dynamic boost value for this document
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may also apply the dynamic boost to a specific field (or even different boosts to different fields), so it only is applied when a hit occurs in the boosted field. This way you can choose at query time if you want to have the boosting applied or not. Just query either the boosted fields, or the normal ones:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
class Article
  acts_as_ferret :fields =&gt; { 
                             :title               =&gt; {}, 
                             :boosted_title =&gt; { :boost =&gt; :rating } 
                         }
  def rating
    # return rating of this article
  end

  # value for the boosted title field
  def boosted_title
    title
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;New and better start/stop scripts&lt;/h3&gt;

&lt;p&gt;The DRb server now has a unified start/stop script and it ships with scripts for using the it as a Windows system service. Thanks to &lt;a href=&quot;http://pmade.com/&quot;&gt;Peter Jones&lt;/a&gt; and &lt;a href=&quot;http://www.pluitsolutions.com/&quot;&gt;Herryanto Siatono&lt;/a&gt; for contributing these. &lt;/p&gt;

&lt;p&gt;Also the acts_as_ferret gem now has got an installer that will install the server script and sample config into your Rails project:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;
$ gem install acts_as_ferret
$ rails test
$ cd test/
$ aaf_install
$ script/ferret_server -e production start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And your DRb server is up and running. Easy, isn&#8217;t it? &lt;/p&gt;

&lt;h3&gt;No more &lt;code&gt;:remote =&amp;gt; true&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Last but not least, aaf now is a bit more clever and goes into remote mode automatically if the DRb server is configured for the current environment. If for whatever reason you don&#8217;t want that, use &lt;code&gt;:remote =&amp;gt; false&lt;/code&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2007-10-31:242</id>
    <published>2007-10-31T10:31:00Z</published>
    <updated>2007-11-01T13:36:29Z</updated>
    <category term="grails"/>
    <category term="hibernate"/>
    <category term="j2ee"/>
    <category term="jruby"/>
    <category term="rails"/>
    <category term="webit"/>
    <link href="http://www.jkraemer.net/2007/10/31/how-i-learned-to-stop-worrying-and-love-jruby-on-rails" rel="alternate" type="text/html"/>
    <title>How I learned to stop worrying and love JRuby on Rails</title>
<content type="html">
            &lt;p&gt;As I &lt;a href=&quot;http://www.jkraemer.net/2007/9/20/railsconf-europe-roundup&quot;&gt;wrote earlier&lt;/a&gt;, I got pretty excited about &lt;a href=&quot;http://www.jruby.org/&quot;&gt;JRuby&lt;/a&gt; and especially about the idea of running Rails on top of it at RailsConf Europe. By pure coincidence we had just had started a project at &lt;a href=&quot;http://www.webit.de/&quot;&gt;webit!&lt;/a&gt; at this time which had to be deployed to the customer&#8217;s J2EE infrastructure. I didn&#8217;t really follow the JRuby development before, and therefore greatly underestimated its level of maturity. So, looking for a Rails-like way to build this application, I decided to go with the &lt;a href=&quot;http://groovy.codehaus.org/&quot;&gt;Groovy&lt;/a&gt;-based &lt;a href=&quot;http://grails.codehaus.org/&quot;&gt;Grails framework&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At first Grails looks and feels much like Rails, however if you look closer and actually try to build a real application with it, the differences start showing up. Don&#8217;t get me wrong, when compared to the more traditional J2EE ways to build web applications (my experiences in this field range from plain Servlets to Struts and Spring), Grails is a huge step into into the right direction. Unfortunately for me, coming from Rails, it just didn&#8217;t feel right or complete in many places. Partly this is for sure because Grails, despite its name, is not just a Rails clone, but does things in its own way in many places. Without going into much more detail here, things often weren&#8217;t working the way I expected, and documentation was often outdated or missing.&lt;/p&gt;

&lt;p&gt;Another issue with Grails for me was &lt;a href=&quot;http://www.hibernate.org/&quot;&gt;Hibernate&lt;/a&gt;, its persistence layer of choice. I simply can&#8217;t get used to the way Hibernate works. In my opinion it abstracts way too much from the database with its own query language and all its object oriented query building glory. Also it seemed to queue up sql statements and execute them at will at some later time, which I found irritating to say the least. I really don&#8217;t understand why Hibernate is &lt;em&gt;the&lt;/em&gt; persistence framework of choice in so many J2EE projects. On the other hand it fits the ugly picture of the bloated J2EE web application quite well ;-)  &lt;/p&gt;

&lt;p&gt;To summarize this rant, don&#8217;t underestimate the learning curve of Grails, which will be even steeper when you aren&#8217;t already used to Hibernate. I think Rails people having to do J2EE development are just not the target audience of Grails. But it might be a good fit for J2EE developers who either already have their Hibernate models in place or at least have the will to invest some serious time in learning Hibernate.&lt;/p&gt;

&lt;p&gt;After all, as you might already have guessed, I decided to start from scratch with JRuby and Rails after RailsConf Europe. And it really felt like coming home from a long and exhausting trip. Despite the lost time in the beginning we met our deadline and had a really great time solving problems the Rails way and deploying to JBoss every now and then. Right now I&#8217;m in the middle of my second JRuby on Rails project, same customer, same target platform. I plan to write some more articles about our experiences with JRuby, so stay tuned.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2007-10-21:241</id>
    <published>2007-10-21T15:13:00Z</published>
    <updated>2007-10-21T15:23:09Z</updated>
    <category term="ferret"/>
    <category term="monit"/>
    <category term="server"/>
    <link href="http://www.jkraemer.net/2007/10/21/keep-an-eye-on-acts_as_ferret-s-drb-server-with-monit" rel="alternate" type="text/html"/>
    <title>Keep an eye on your DRb server with Monit</title>
<content type="html">
            &lt;p&gt;Many people nowadays seem to use &lt;a href=&quot;http://www.tildeslash.com/monit/&quot;&gt;monit&lt;/a&gt; to ensure their Rails application is always up and running, and maybe even to get notified in case of any problems like unusual high load or memory usage.&lt;/p&gt;

&lt;p&gt;Since acts_as_ferret doesn&#8217;t really like it when the DRb server has gone away, it&#8217;s a good idea to not only monitor your Mongrels, but also the DRb server itself. So here&#8217;s for you a small snippet of monit configuration derived from one I&#8217;m using elsewhere:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;&quot;&gt;# monit configuration snippet to watch the Ferret DRb server shipped with
# acts_as_ferret
check process ferret with pidfile /path/to/ferret.pid

    # username is the user the drb server should be running as (It's good practice
    # to run such services as a non-privileged user)
    start program = &quot;/bin/su -c 'cd /path/to/your/app/current/ &amp;&amp; RAILS_ENV=production script/ferret_start' username&quot;
    stop program = &quot;/bin/su -c 'cd /path/to/your/app/current/ &amp;&amp; RAILS_ENV=production script/ferret_stop' username&quot;

    # cpu usage boundaries
    if cpu &gt; 60% for 2 cycles then alert
    if cpu &gt; 90% for 5 cycles then restart

    # memory usage varies with index size and usage scenarios, so check how
    # much memory your DRb server uses up usually and add some spare to that
    # before enabling this rule:
    # if totalmem &gt; 50.0 MB for 5 cycles then restart

    # adjust port numbers according to your setup:
    if failed port 9010 then alert
    if failed port 9010 for 2 cycles then restart
    group ferret
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see it&#8217;s pretty straightforward, well, maybe except the start/stop commands which took me a few iterations to get right. I also added this to the acts_as_ferret distribution: &lt;a href=&quot;http://projects.jkraemer.net/acts_as_ferret/browser/trunk/plugin/acts_as_ferret/doc/monit-example&quot;&gt;monit-example&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2007-10-15:240</id>
    <published>2007-10-15T21:00:00Z</published>
    <updated>2007-10-21T15:24:26Z</updated>
    <category term="blog action day"/>
    <category term="environment"/>
    <category term="the nag"/>
    <link href="http://www.jkraemer.net/2007/10/15/the-nag-make-the-world-a-better-place-step-by-step" rel="alternate" type="text/html"/>
    <title>The Nag - make the world a better place step by step</title>
<content type="html">
            &lt;p&gt;Because today is &lt;a href=&quot;http://blogactionday.org/&quot;&gt;blog action day&lt;/a&gt;, I&#8217;ll tell you a bit about an interesting project I&#8217;ve been helping to create during the last few months.&lt;/p&gt;

&lt;p&gt;I think most people actually want to do something about certain issues like climate change or poverty in the world, but they tend to forget about it being busy with other stuff, or they simply don&#8217;t know where to start. I for sure am one of this kind&#8230;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.thenag.net/&quot;&gt;&lt;img src=&quot;http://www.thenag.net/images/nagbanner_200x270.jpg&quot; alt=&quot;Join The Nag&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To help these people, &lt;a href=&quot;http://www.antiapathy.org&quot;&gt;Antiapathy.org&lt;/a&gt; created &lt;a href=&quot;http://www.thenag.net/&quot;&gt;The Nag&lt;/a&gt; It&#8217;s a platform where you can register to get nagged once a month with a small, accomplishable task to help solve a certain issue. The web site supplies background information and links to sources of further information on many different issues, and users are guided step by step through each task on the web site.&lt;/p&gt;

&lt;p&gt;Tasks range from asking the makers of your clothes whether they&#8217;re paying their workers fair wages to switching your home&#8217;s energy supply to green energy.&lt;/p&gt;

&lt;p&gt;The fun part is that the application collects all that data and aggregates it on a &lt;a href=&quot;http://thenag.net/energy/impact&quot;&gt;map&lt;/a&gt; so everybody can see the  impact all members have made, and which regions in the UK are the most active. So if you live in the UK and want to do something good, but you need a little reminder every now and then, why not give it a try?&lt;/p&gt;

&lt;p&gt;Not living in the UK of course is no excuse for doing nothing - since I live in Germany, my recent switch to &lt;a href=&quot;http://www.greenpeace-energy.de/&quot;&gt;Greenpeace Energy&lt;/a&gt; unfortunately doesn&#8217;t affect The Nag&#8217;s total impact, but it&#8217;s a good feeling anyway :-)&lt;/p&gt;

&lt;p&gt;And they have this &lt;a href=&quot;http://www.greenpeace-energy.de/strom_barometer.php&quot;&gt;neat thingy&lt;/a&gt; showing where your energy &lt;em&gt;right now&lt;/em&gt; is coming from&#8230;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2007-09-20:237</id>
    <published>2007-09-20T19:09:00Z</published>
    <updated>2007-09-20T19:37:24Z</updated>
    <category term="conference"/>
    <category term="rails"/>
    <category term="railsconf"/>
    <category term="ruby"/>
    <link href="http://www.jkraemer.net/2007/9/20/railsconf-europe-roundup" rel="alternate" type="text/html"/>
    <title>Railsconf Europe Roundup</title>
<content type="html">
            &lt;p&gt;With more than 3 days full of Rails and fun and meeting cool people from all around the world behind me, here&#8217;s what I took home from Railsconf Europe:&lt;/p&gt;

&lt;h3&gt;Sun and ThoughtWorks are really pushing JRuby&lt;/h3&gt;

&lt;p&gt;JRuby has been &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14263&quot;&gt;covered&lt;/a&gt; &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14248&quot;&gt;in&lt;/a&gt; &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14941&quot;&gt;4&lt;/a&gt; &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14885&quot;&gt;talks&lt;/a&gt; by speakers from both Sun and ThoughtWorks, who also were among the diamond sponsors of the conference. &lt;/p&gt;

&lt;p&gt;It really looks like JRuby is ready for real life usage in J2EE environments, effectively bringing Rails into the so-called enterprise through the backdoor. Or, as Ola Bini put it,&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;JRuby is just another Java library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pretty impressed I immediately tried this stuff out - and it really works :-) Time to ditch &lt;a href=&quot;http://grails.codehaus.org/&quot;&gt;Grails&lt;/a&gt; and have some fun with my favourite language instead.&lt;/p&gt;

&lt;h3&gt;Selenium&lt;/h3&gt;

&lt;p&gt;Till Vollmer&#8217;s &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14215&quot;&gt;presentation&lt;/a&gt; of the browser-based testing tool &lt;a href=&quot;http://www.openqa.org/selenium/&quot;&gt;Selenium&lt;/a&gt; was quite impressive. I definitely have to try this out.&lt;/p&gt;

&lt;h3&gt;Webistrano&lt;/h3&gt;

&lt;p&gt;At &lt;a href=&quot;http://www.rug-b.de/wiki/show/RejectConf&quot;&gt;Rejectconf&lt;/a&gt; which was organized by the Berlin Rails User Group, &lt;a href=&quot;http://blog.innerewut.de/&quot;&gt;Jonathan Weiss&lt;/a&gt; gave a short introduction to &lt;a href=&quot;http://blog.innerewut.de/webistrano/&quot;&gt;Webistrano&lt;/a&gt;, which is a web-based frontend to Capistrano. Great way to get designers and editors without a local Ruby/Capistrano installation involved in the development process.&lt;/p&gt;

&lt;h3&gt;Report #12&lt;/h3&gt;

&lt;p&gt;Besides telling us that it&#8217;s time to put the party hats and James Dean jackets aside for a while, and instead get some real work done (and of course have fun) with Rails, DHH introduced &lt;a href=&quot;http://dev.rubyonrails.org/report/12&quot;&gt;report #12&lt;/a&gt;, which basically is a list of well-tested patches that have been approved by at least 3 other people. This formalization of the peer-review process is a really good thing as it takes some of the work load away from the core team and makes it easier for people to contribute.&lt;/p&gt;

&lt;h3&gt;Rails developers are happier&lt;/h3&gt;

&lt;p&gt;We all knew this, but it&#8217;s good even Sun&#8217;s Craig R. McClanahan noted in his &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14939&quot;&gt;inspiring talk&lt;/a&gt; that he never saw that many friendly and happy people at JavaOne, as he saw at Railsconf Europe. He also admitted that going back to Java after having worked with Rails is not that pleasant. Just to remind you - he&#8217;s working at the company whose ticker symbol is &lt;code&gt;JAVA&lt;/code&gt;&#8230;&lt;/p&gt;

&lt;p&gt;All in all it was a great event, and even with &lt;a href=&quot;http://drnicwilliams.com/2007/09/07/why-you-should-see-dr-nic-at-railsconf/&quot;&gt;Dr Nic speaking at the same time&lt;/a&gt; &lt;a href=&quot;http://www.jkraemer.net/assets/2007/9/20/rails_ftsearch_with_ferret.pdf&quot;&gt;my own talk&lt;/a&gt; was pretty well attended, &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.jkraemer.net/">
    <author>
      <name>jk</name>
    </author>
    <id>tag:www.jkraemer.net,2007-09-09:230</id>
    <published>2007-09-09T14:48:00Z</published>
    <updated>2007-09-09T15:24:24Z</updated>
    <category term="ferret"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://www.jkraemer.net/2007/9/9/raise-your-hand-please-if-you-re-using-ferret" rel="alternate" type="text/html"/>
    <title>Raise your hand please if you're using Ferret</title>
<content type="html">
            &lt;p&gt;Working on &lt;a href=&quot;/projects/acts_as_ferret&quot;&gt;acts_as_ferret&lt;/a&gt; for more than one and a half year now, I&#8217;m really interested in why and how people are using it in their applications. Also, a list of Ferret-powered projects will be a good starting point for people who are still looking for a search solution for their Rails app.&lt;/p&gt;

&lt;p&gt;So if you&#8217;re using Ferret, please drop me a line, comment here, or even add your application to the &lt;a href=&quot;http://ferret.davebalmain.com/trac/wiki/PoweredBy&quot;&gt;Powered by Ferret&lt;/a&gt; page over at the Ferret project&#8217;s Trac. Ideally you would also post some facts like index size, your production environment or even performance numbers. Personally I&#8217;d also like to know if you&#8217;re using acts_as_ferret, or, if that&#8217;s not the case, why you decided to go with pure Ferret.&lt;/p&gt;

&lt;p&gt;I&#8217;ll also mention some sites that make use of Ferret in my &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14163&quot;&gt;talk at Railsconf Europe&lt;/a&gt; next week. So if you&#8217;re looking for some publicity, what are you waiting for?&lt;/p&gt;
          </content>  </entry>
</feed>
