<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Futurechimp - Home</title>
  <id>tag:futurechimp.org,2010:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://futurechimp.org/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://futurechimp.org/" rel="alternate" type="text/html"/>
  <updated>2010-09-09T12:01:52Z</updated>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-09-09:48</id>
    <published>2010-09-09T10:55:00Z</published>
    <updated>2010-09-09T12:01:52Z</updated>
    <category term="ruby-debug19"/>
    <category term="rvm"/>
    <category term="ubuntu"/>
    <link href="http://futurechimp.org/2010/9/9/ruby-debug19-on-ubuntu-10-04-with-rvm" rel="alternate" type="text/html"/>
    <title>ruby-debug19 on Ubuntu 10.04 (with rvm)</title>
<content type="html">
            &lt;p&gt;Note to self:  the newest available version of ruby-debug19 will fail brutally like this on the Ubuntu 10.04:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;$ ruby -Ilib:test test/controllers/test_my_account_controller.rb 
/home/dave/.rvm/gems/ruby-1.9.1-p378/gems/ruby-debug-base19-0.11.24/lib/ruby-debug-base.rb:1:in `require': no such file to load -- ruby_debug.so (LoadError)&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;To avoid this unpleasant fate, uninstall the latest versions of ruby-debug19 and ruby-debug-base19 (which are both at 0.11.24):&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;gem uninstall ruby-debug19
gem uninstall ruby-debug-base19&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;For some reason, that didn&#8217;t do the trick for me and I also had to manually remove the installed gem files from rvm&#8217;s gems folder:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;rm -Rf ~/.rvm/gems/ruby-1.9.1-p378/gems/ruby-debug-base19-0.11.24/&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;After that, the gem installed just fine, one patch point back:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;gem install ruby-debug-base19 -v=0.11.23
gem install ruby-debug19&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-09-03:47</id>
    <published>2010-09-03T10:23:00Z</published>
    <updated>2010-09-29T20:14:57Z</updated>
    <category term="couchdb"/>
    <category term="ubuntu 10.04"/>
    <link href="http://futurechimp.org/2010/9/3/installing-couchdb-1-0-1-on-ubuntu-10-04" rel="alternate" type="text/html"/>
    <title>Installing CouchDb 1.0.1 on Ubuntu 10.04</title>
<content type="html">
            &lt;p&gt;CouchDb 1.0.1 is hard to install from source on Ubuntu 10.04, mainly because
the libmozjs-dev package doesn&#8217;t exist in the apt repos. If you try following
the CouchDb install from source directions, you&#8217;ll get a message like this:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;configure: error: Could not find the js library.&lt;/code&gt;&lt;/pre&gt;


	&lt;pre&gt;&lt;code&gt;Is the Mozilla SpiderMonkey library installed?&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;CouchDb relies on Mozilla&#8217;s SpiderMonkey javascript engine, but that&#8217;s not
available in Ubuntu 10.04.&lt;/p&gt;


	&lt;p&gt;This should install most dependencies:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;sudo apt-get build-dep couchdb&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;In case build-dep didn&#8217;t get this one:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;sudo apt-get install xulrunner-dev&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Grab the SpiderMonkey source from the Mozilla website, build it, and install it:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;wget http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz
tar -xvzf js-1.8.0-rc1.tar.gz
cd js/src
make BUILD_OPT=1 -f Makefile.ref
sudo make BUILD_OPT=1 JS_DIST=/usr/local -f Makefile.ref export&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;That&#8217;ll build and install libjs &#8211; but after a reboot, couchdb may lose track of where you&#8217;ve installed libjs. You could mess around with environment variables every time you spark up couch, but you might want to make it more permanent by informing ldconfig of the library&#8217;s location.  Assuming you&#8217;re on 64-bit, you can do this:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;sudo touch /etc/ld.so.conf.d/spidermonkey.conf
sudo echo &quot;/usr/local/lib64&quot; &amp;gt;/etc/ld.so.conf.d/spidermonkey.conf
sudo ldconfig&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Adjust as necessary for 32-bit systems if you&#8217;re running one of those.&lt;/p&gt;


	&lt;p&gt;After that you should have no trouble grabbing the CouchDb source, untarring it,
and doing the configure-make-make-install dance:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;wget http://apache.mirror.anlx.net//couchdb/1.0.1/apache-couchdb-1.0.1.tar.gz
tar -xvzf apache-couchdb-1.0.1.tar.gz
cd apache-couchdb-1.0.1
./configure &#38;&#38; make &#38;&#38; sudo make install&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-07-12:45</id>
    <published>2010-07-12T15:29:00Z</published>
    <updated>2010-07-20T14:54:45Z</updated>
    <category term="datamapper"/>
    <category term="enigmamachine"/>
    <category term="eventmachine"/>
    <category term="ffmpeg"/>
    <category term="sinatra"/>
    <category term="thin"/>
    <link href="http://futurechimp.org/2010/7/12/enigmamachine-first-working-release" rel="alternate" type="text/html"/>
    <title>Enigmamachine - first working release</title>
<content type="html">
            &lt;p&gt;I&#8217;ve just put the finishing touches on the first working release of &lt;a href=&quot;http://github.com/futurechimp/enigmamachine&quot;&gt;Enigmamachine&lt;/a&gt;.  It&#8217;s a RESTful video encoder written in Ruby.  It uses the &lt;a href=&quot;http://code.macournoyer.com/thin/&quot;&gt;thin&lt;/a&gt; webserver, &lt;a href=&quot;http://rubyeventmachine.com&quot;&gt;eventmachine&lt;/a&gt; event framework, &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;sinatra&lt;/a&gt; web framework, and &lt;a href=&quot;http://datamapper.org&quot;&gt;datamapper&lt;/a&gt; ORM.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;There&#8217;s a lot more info in the &lt;a href=&quot;http://github.com/futurechimp/enigmamachine&quot;&gt;&lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt;&lt;/a&gt;, but basically it&#8217;s a standalone &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; service which accepts a &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request triggering a video encode on the local filesystem.  In short, your web app gets a video uploaded to it, and once it&#8217;s saved on your filesystem, you&#8217;d do something like:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;wget http://username:password@localhost:2002/videos --post-data 'video[file]=/path/to/your/video.mp4&#38;encoder_id=1'&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;This would apply whatever ffmpeg tasks you define to the uploaded video.  Advantages for you?  You don&#8217;t need to worry about process daemonization, threading issues, or maintaining a processing queue, you just fire off a &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request and enigmamachine does the rest.&lt;/p&gt;


	&lt;p&gt;There aren&#8217;t any callbacks yet, and I can see that this is probably the next thing to do (as well as slugging the encoder_id).  That&#8217;ll wait, though.  Basically it&#8217;s ready for first use, after a long long time messing with the idiosyncracies of combining ffmpeg (which logs to stderr), thin, a gem binary, and eventmachine&#8217;s multi-threaded mode.  This was an interesting process all on its own, and I&#8217;ll do a write-up about Thin daemonization soon, as I think it&#8217;s a really great way to make low-ceremony services in Ruby.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-03-26:40</id>
    <published>2010-03-26T14:29:00Z</published>
    <updated>2010-03-26T14:34:42Z</updated>
    <category term="carcrashes"/>
    <category term="cops"/>
    <link href="http://futurechimp.org/2010/3/26/every-picture-tells-a-story" rel="alternate" type="text/html"/>
    <title>Every picture tells a story</title>
<content type="html">
            &lt;p&gt;I&#8217;m not much of a photographer but I couldn&#8217;t resist a snap of this situation, which we strolled past yesterday during a walk-and-talk session discussing some development issues:&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-03-19:38</id>
    <published>2010-03-19T23:53:00Z</published>
    <updated>2010-03-20T00:25:05Z</updated>
    <category term="gem"/>
    <category term="upload_column"/>
    <link href="http://futurechimp.org/2010/3/19/uploadcolumn-gem-released" rel="alternate" type="text/html"/>
    <title>UploadColumn Gem Released</title>
<content type="html">
            &lt;p&gt;As part of a series of experiments with the Rails 3 beta, I&#8217;ve started gemifying a pile of plugin code we&#8217;re using.  Rails Engines in Rails 3 are completely integrated into the framework (every Rails app is now a Rails::Engine!) so there are going to be some exciting times ahead as we start building modular apps which can be distributed with versioned gem dependencies.  Part of the fun will be turning plugins into gems wherever possible, so that library code can be cleanly integrated into the modular apps, and everything is quick to set up at the start of a project.&lt;/p&gt;


	&lt;p&gt;The first fruit of this is the &lt;a href=&quot;http://rubygems.org/gems/uploadcolumn&quot;&gt;UploadColumn&lt;/a&gt; gem, which is just the venerable &lt;a href=&quot;http://uploadcolumn.rubyforge.org/&quot;&gt;UploadColumn Plugin&lt;/a&gt; wrapped up and packaged as a rubygem.  It works in the same way it always has, except that you can include it in your project by doing a:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;sudo gem install uploadcolumn&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;and then a:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;config.gem 'uploadcolumn', :lib =&amp;gt; 'upload_column'&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;The code is forked out on Github, &lt;a href=&quot;http://github.com/futurechimp/uploadcolumn&quot;&gt;dive in&lt;/a&gt; and start hacking on it if you are an upload_column user. The tests must be for an earlier version of RSpec (they no longer run even in the canonical JNicklas repo), we&#8217;ll have to do some cleanup work when we get a chance.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-03-16:37</id>
    <published>2010-03-16T15:35:00Z</published>
    <updated>2010-03-16T15:35:23Z</updated>
    <category term="2007"/>
    <category term="2010"/>
    <category term="9.10"/>
    <category term="evolution"/>
    <category term="exchange"/>
    <category term="karmic"/>
    <category term="koala"/>
    <category term="mapi"/>
    <category term="ubuntu"/>
    <link href="http://futurechimp.org/2010/3/16/mapi-is-evolving" rel="alternate" type="text/html"/>
    <title>MAPI is Evolving</title>
<content type="html">
            &lt;p&gt;Recent changes to the email infrastructure around here have meant that those of us on Linux still have some troubles.  The Exchange 2007 &lt;span class=&quot;caps&quot;&gt;MAPI&lt;/span&gt; connector seems to work pretty well for Mac users, but Evolution&#8217;s &lt;span class=&quot;caps&quot;&gt;MAPI&lt;/span&gt; provider plugin in Ubuntu 9.10 doesn&#8217;t work particularly well at present.  It screws up calendars and inserts some strange entities (&#8221;=20&#8221;) on line breaks in emails, making us seem even geekier than we actually are.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;On the upside, Evolution doesn&#8217;t freak out very often, as it did with the Exchange 2003 connector.  So what happens if we try and compile the &lt;span class=&quot;caps&quot;&gt;MAPI&lt;/span&gt; connector from source?&lt;/p&gt;


&lt;pre&gt;
#!/bin/sh

#Shut down all running evolution processes
evolution --force-shutdown

# Make somewhere for the source code to live
mkdir ~/evolution
cd ~/evolution

#Download source code from gnome-evolution project page
wget http://download.gnome.org/sources/evolution-mapi/0.28/evolution-mapi-0.28.3.tar.bz2
wget http://download.gnome.org/sources/gtkhtml/3.28/gtkhtml-3.28.3.tar.bz2

#Remove evolution-MAPI package
sudo apt-get remove evolution-mapi

#Install needed dependencies for compilation
sudo apt-get install libdb-dev libnspr4-dev libnss3-dev libical-dev libsqlite3-dev
sudo apt-get install bison intltool gnome-core-devel evolution-data-server-dev 
sudo apt-get install libcanberra-gtk-dev
sudo apt-get install libgtkhtml3.8-dev network-manager-dev libunique-dev libhal-dev
sudo apt-get install libgtkimageview-dev libpst-dev libnotify-dev
sudo apt-get install libmapi-dev samba4-dev libglib2.0-dev
sudo apt-get install libebackend1.2-dev libecal1.2-dev libedataserver1.2-dev
sudo apt-get install  libedata-cal1.2-dev  libebook1.2-dev libedata-book1.2-dev
sudo apt-get install libcamel1.2-dev evolution-dev libedataserverui1.2-dev

# Compile gtkhtml
tar fxj gtkhtml-3.28.3.tar.bz2
cd gtkhtml-3.28.3
./configure &#38;&#38; make &#38;&#38; sudo make install
cd ..

# Compile the mapi plugin
tar fxj evolution-mapi-0.28.3.tar.bz2
cd evolution-mapi-0.28.3
./configure &#38;&#38; make &#38;&#38; sudo make install
cd ..

# Now you can just start evolution normally and enjoy some improvements!
&lt;/pre&gt;

	&lt;p&gt;Calendar invites still screw up and disappear randomly, but at least emails don&#8217;t have weird entities strewn all through them, making me feel a little better about things.  Hopefully this package will get some love in the forthcoming Ubuntu 10.04!  Thanks to the Ubuntu Forums people for &lt;a href=&quot;http://ubuntuforums.org/showpost.php?p=8743142&amp;amp;postcount=82&quot;&gt;providing partial instructions&lt;/a&gt; for how to compile these packages (I&#8217;ve turned that forum post into a shell script that should hopefully work for most people).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; this process only works if you&#8217;ve already got your Exchange &lt;span class=&quot;caps&quot;&gt;MAPI&lt;/span&gt; account set up and properly configured.  Installing the evolution-mapi-0.28.3 plugin breaks the UI which is used to enter your account details right at the start of the Evolution setup process, making it impossible to set up any kind of account. This somewhat sucks but I guess if you&#8217;ve already got your account set up, it won&#8217;t make much difference to you.&lt;/p&gt;


	&lt;p&gt;The shell script, ready to go, is &lt;a href=&quot;http://futurechimp.org/assets/2010/3/16/install-latest-evolution-mapi-from-source.sh&quot;&gt;here&lt;/a&gt;.  If it eats your dog or provokes an existential crisis, you can back out of the changes it makes like so:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;evolution --force-shutdown
cd ~/.evolution
cd evolution-mapi-0.28.3 &#38;&#38; sudo make uninstall &#38;&#38; cd ..  
cd gtkhtml-3.28.3  &#38;&#38; sudo make uninstall &#38;&#38; cd .. 
sudo apt-get install exchange-mapi&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-03-10:36</id>
    <published>2010-03-10T17:17:00Z</published>
    <updated>2010-03-10T17:29:46Z</updated>
    <category term="dm-crypt"/>
    <category term="encryption"/>
    <category term="rdp"/>
    <category term="ubuntu"/>
    <category term="virtualbox"/>
    <category term="virtualization"/>
    <category term="vrdp"/>
    <link href="http://futurechimp.org/2010/3/10/headless-virtualbox-dm-crypt-and-vrdp" rel="alternate" type="text/html"/>
    <title>Headless Virtualbox, dm-crypt, and VRDP</title>
<content type="html">
            &lt;p&gt;So we just got a new server machine into the office, and it&#8217;s got some major stonk so that we can move towards virtualised services in a big way.  The machine is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Gort_%28The_Day_the_Earth_Stood_Still%29&quot;&gt;gort&lt;/a&gt;, and it dominates:&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;As a result, we&#8217;ve got a few new file servers for specific purposes, and they&#8217;re running &lt;a href=&quot;http://www.samba.org/&quot;&gt;samba&lt;/a&gt; on Linux on top of &lt;a href=&quot;http://virtualbox.org&quot;&gt;Virtualbox&lt;/a&gt; rather than &lt;span class=&quot;caps&quot;&gt;SMB&lt;/span&gt; on Windows.  Some of them have sensitive data, which we want to protect in case of theft, so I&#8217;ve encrypted the crap out of everything using &lt;a href=&quot;http://en.wikipedia.org/wiki/Dm-crypt&quot;&gt;dm-crypt&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I was initially stumped as to how to make this whole setup work properly. A dm-crypt disk volume needs its encryption passphrase entered before it even begins to boot.  However, the Virtualbox machine image needs to run using VBoxHeadless, without any kind of graphical interface, because we want to be able to boot the whole setup remotely via a console if a machine image goes down for some reason.  It seemed like there was going to be a problem &#8211; either we could run the setup headless and not have to come into the office if a machine crashed, or have dm-crypt encryption as an anti-theft strategy, but not both.&lt;/p&gt;


	&lt;p&gt;The solution turned out to be remarkably simple.&lt;/p&gt;


	&lt;p&gt;Any Virtualbox VM image started using a command like&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;VBoxHeadless -startvm &quot;FooBox&quot;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;automatically gets its own display server running something called &#8220;VRDP&#8221; (which I assume is maybe &#8220;Virtualbox Remote Desktop Protocol&#8221;).  The first VM listens on port 3689 of the host server, and you need to explicitly tell any further VMs to listen on a different port, perhaps like so:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;VBoxHeadless --startvm &quot;Some Machine Image&quot; -v on -vrdpport 5000 &#38;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;This will tell Virtualbox to start the VM called &#8220;Some Machine Image&#8221; and turn on the &lt;span class=&quot;caps&quot;&gt;VRDP&lt;/span&gt; server on port 5000 (and the relinquish control of the terminal back to stdin due to the ampersand).  Assuming that the host server has a hostname of &#8220;foo.bar.blah&#8221; on your network, you can then use your regular Remote Desktop Protocol (RDP) client to connect to the host server on port 5000.  You&#8217;ll be shown the current state of the guest VM right from the moment it initially boots, allowing you to type your encryption passphrase in.&lt;/p&gt;


	&lt;p&gt;So the process basically looks like this:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;dave@gort:&lt;sub&gt;$ VBoxHeadless --startvm &quot;Some Machine Image&quot; -v on -vrdpport 5000 &#38;
[1] 8905
dave@gort:&lt;/sub&gt;$ Sun VirtualBox Headless Interface 3.1.4
(C) 2008-2010 Sun Microsystems, Inc.
All rights reserved.&lt;/code&gt;&lt;/pre&gt;


	&lt;pre&gt;&lt;code&gt;Listening on port 5000.&lt;/code&gt;&lt;/pre&gt;


	&lt;pre&gt;&lt;code&gt;dave@gort:~$&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;At that point, the VM image has fired up and is running, but it isn&#8217;t booting, because it needs its passphrase before it can access its system files and start to boot.&lt;/p&gt;


	&lt;p&gt;So, we can connect to the &lt;strong&gt;host&lt;/strong&gt; machine (don&#8217;t bother trying to connect to the guest machine yet).  One very important thing to note is that &lt;span class=&quot;caps&quot;&gt;VRDP&lt;/span&gt; only worked for me using &lt;strong&gt;RDPv5&lt;/strong&gt;:&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;This gets us right on to the VM image&#8217;s grub screen, and then to the dm-crypt passphrase entry.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;Entering the passphrase allows boot to continue normally.  I&#8217;ve got to say, I&#8217;ve been pleasantly surprised by easy Virtualbox has made everything.  The admin tools are first-rate and convenient to use, networking has been easy to set up, and the learning curve has been low.  Now I can take all the time I&#8217;ve saved and use it to mess with &lt;a href=&quot;http://www.linux-kvm.org/page/Main_Page&quot;&gt;kvm&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-02-17:35</id>
    <published>2010-02-17T18:37:00Z</published>
    <updated>2010-02-17T18:41:11Z</updated>
    <category term="backups"/>
    <category term="rsync"/>
    <category term="smb"/>
    <link href="http://futurechimp.org/2010/2/17/rsync-samba-don-t-archive" rel="alternate" type="text/html"/>
    <title>Rsync + Samba: Don't Archive!</title>
<content type="html">
            &lt;p&gt;Just a quick note to self (and whoever else it might help) &#8211;  when doing an rsync backup to a mounted &lt;span class=&quot;caps&quot;&gt;SMB&lt;/span&gt; file share, this works:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;rsync -rvz --progress /path/to/source /path/to/destination/&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;This doesn&#8217;t:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;rsync -avz --progress /path/to/source /path/to/destination/&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;The -a option (&#8220;archive&#8221;) doesn&#8217;t work properly with &lt;span class=&quot;caps&quot;&gt;SMB&lt;/span&gt;, so the files are never copied.  Thanks to &lt;a href=&quot;http://www.thelinuxblog.com/rsync-to-smb-share/&quot;&gt;the Linux Blog&lt;/a&gt; for that one!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-02-02:34</id>
    <published>2010-02-02T13:57:00Z</published>
    <updated>2010-02-02T14:05:14Z</updated>
    <category term="agile"/>
    <category term="hubbub"/>
    <category term="rails"/>
    <category term="testing"/>
    <link href="http://futurechimp.org/2010/2/2/hubbub-a-quick-tour" rel="alternate" type="text/html"/>
    <title>Hubbub: A Quick Tour</title>
<content type="html">
            &lt;p&gt;We recently did some &lt;a href=&quot;http://blog.headlondon.com/2009/12/15/hubbub-deliveries-site-design-launch/&quot;&gt;e-commerce work&lt;/a&gt; for an online startup called &lt;a href=&quot;http://hubbubdeliveries.co.uk&quot;&gt;Hubbub&lt;/a&gt;.  We&#8217;re pretty proud of it here, so it seems worth it to talk a little about the challenges involved in building it.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;Most e-commerce jobs are relatively simple from a business process point of view &#8211; one website has one shop inside it, and in most cases, when you buy something it instantly gets sent for fulfillment (either physically or digitally).  For example, if you buy a pair of shoes from &lt;a href=&quot;http://shoemanic.com&quot;&gt;Humanic&lt;/a&gt; (which we worked on last year), the shoes move into the delivery system immediately, and are usually sent out the next day.  Fulfillment, i.e. the delivery of your shoes, is handled by a dedicated service provider external to the website itself.&lt;/p&gt;


	&lt;p&gt;Hubbub is completely different.  Instead of having one shop and a relatively simple delivery system, the site is composed of multiple shops (a baker, an Italian deli, a fish shop, etc) which are in a delivery area &#8211; so the Hubbub site needs to keep track of which products have been ordered from which shops.  New shops and new delivery areas can be added at any time.  If Hubbub decides to expand into Kensington, Chelsea, and Clapham tomorrow, it can add those three neighbourhoods as new delivery areas, and add the shops from each neighbourhood into the right area.  Specialist shops (like Christchurch Fish, which can serve all of London) can be shared across multiple delivery areas.  The site then keeps track of which shops have had which items ordered from them.&lt;/p&gt;


	&lt;p&gt;Items can be scheduled for delivery on a specific hour anytime in the 30 days from the date of purchase.  The site has its own fulfilment system built into it, automating the scheduling of store pick-ups and item deliveries for each delivery area on an hourly basis. Delivery drivers have their pickup and delivery schedules emailed to them every day in the early afternoon, allowing them to plan out their routes for the day.  All in all, the site code is much more than a simple webshop, it&#8217;s a fully integrated customized e-commerce software platform which enables Hubbub to function. It&#8217;s arguable that the Hubbub business would be impossible without the code to back it up.&lt;/p&gt;


	&lt;p&gt;Most sites take payment when a customer orders an item.  On Hubbub, this isn&#8217;t possible because the price of the item may not be known when it&#8217;s ordered.  In the case of a steak, a chicken, or a bag of fruit, for instance, the site may give an indicative price (steak is £3.99/lb), but the actual price of the steak which will be delivered isn&#8217;t known until the butcher actually cuts it up and weighs it on the day of delivery.  This is a huge issue from a business process point of view. In order to make this relatively complex payment flow work, we &lt;a href=&quot;http://futurechimp.org/2009/10/7/breadmachine-an-3-d-secure-capable-xpay-gem-for-ruby&quot;&gt;wrote&lt;/a&gt; our own payment gateway integration code so that we can do &lt;a href=&quot;http://github.com/mattsoutherden/breadmachine&quot;&gt;3-D Secure authentication with the SecureTrading Xpay gateway&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The end result is a site which looks deceptively simple.  It unifies multiple webshops (which correspond to multiple real-world businesses) into a unified front-end, offering each shop its own login area for product management and order tracking.  The Hubbub site administrators also have their own secure login area which allows them to track the progress of the business.&lt;/p&gt;


	&lt;p&gt;The shop code is based on a heavily-modified version of &lt;a href=&quot;http://spreecommerce.com/&quot;&gt;Spree&lt;/a&gt; retrofitted with our own internal role-based access control systems and an extensive test suite based on &lt;a href=&quot;http://github.com/thoughtbot/shoulda&quot;&gt;shoulda&lt;/a&gt;, &lt;a href=&quot;http://github.com/notahat/machinist&quot;&gt;machinist&lt;/a&gt; and &lt;a href=&quot;http://cukes.info&quot;&gt;cucumber&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;If we made one mistake during development, it was to write too much new code before we&#8217;d adequately covered the Spree codebase with tests we liked.  The default Spree comes with an rspec test suite which was incomplete (when we forked the code from Spree six months ago) &#8211; we like Shoulda and Test::Unit better, so we rewrote the suite.  We should have gone all the way with the code coverage before writing any new code, though &#8211; it was amazing how much our development effort sped up once we got code coverage above ~70%.  For new projects, we&#8217;ve instituted a 95% code coverage minimum on our &lt;a href=&quot;http://cruisecontrolrb.thoughtworks.com/&quot;&gt;CruiseControl&lt;/a&gt; server (with an actual internal target of 100%).&lt;/p&gt;


	&lt;p&gt;It&#8217;s a pretty good feeling &#8211; over the past few years, we&#8217;ve gotten &lt;em&gt;way&lt;/em&gt; more agile.  Codewise at least.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-02-01:33</id>
    <published>2010-02-01T15:46:00Z</published>
    <updated>2010-02-01T16:01:10Z</updated>
    <link href="http://futurechimp.org/2010/2/1/rails-duckboards" rel="alternate" type="text/html"/>
    <title>Rails Duckboards</title>
<content type="html">
            &lt;p&gt;These days, Rails is no longer the hot new thing in the way that it once was &#8211; as programming frameworks go, it&#8217;s settling happily into a vigorous middle age.  The good thing about this is that it means a lot of those awkward teen moments are a thing of the past, and that the experimental choices of early adulthood have given way to a stable, productive lifestyle.&lt;/p&gt;


	&lt;p&gt;However, for anyone who is new to Rails, the learning curve can be very steep.  For those of us who&#8217;ve been using Rails for years (I&#8217;ve been at it since -v=0.11), it&#8217;s easy to take for granted the amount of knowledge that we&#8217;ve accumulated without thinking about it.  Given the choice of several million blog posts, screencasts, and mailing list postings about Rails, I suspect it wouldn&#8217;t be an easy thing these days to start fresh.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;So, it seems worth it to try and provide some &lt;a href=&quot;http://en.wikipedia.org/wiki/Duckboards&quot;&gt;duckboards&lt;/a&gt; for new users.  There&#8217;s a swamp of old blog posts, incorrect information, and simple irrelevance out there on the internetz, and it seems worth it to try and help out newcomers.  Outlining what libraries we&#8217;re using here also seems like a good idea when they are different to the framework defaults (and worth it for a newbie).&lt;/p&gt;


	&lt;p&gt;So, if I had to give some advice to people learning Rails today, I&#8217;d tell them to focus on:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;a good idea of where application logic should go&lt;/li&gt;
		&lt;li&gt;a firm understanding of &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Base.html&quot;&gt;ActiveRecord&lt;/a&gt;, its relationships, and when &lt;strong&gt;not&lt;/strong&gt; to use it&lt;/li&gt;
		&lt;li&gt;test-first experience with &lt;a href=&quot;http://rspec.info/&quot;&gt;Rspec&lt;/a&gt;, &lt;a href=&quot;http://github.com/thoughtbot/shoulda&quot;&gt;Shoulda&lt;/a&gt;, and/or &lt;a href=&quot;http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html&quot;&gt;Test::Unit&lt;/a&gt; (or all three)&lt;/li&gt;
		&lt;li&gt;good understanding of what RESTful routing is and how to use it&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt; coding style&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Skinny Controllers &#8211; Fat Models&lt;/h2&gt;


	&lt;p&gt;It&#8217;s easy to succumb to the temptation to pack all application logic into the controllers, but it&#8217;s a mistake, as detailed in Jamis Buck&#8217;s classic blog post &lt;a href=&quot;http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model&quot;&gt;Skinny Controller, Fat Model&lt;/a&gt;.  Rails controllers should respond to form input in the minimum amount of code possible &#8211; the more application logic gets offloaded into the models, the better.&lt;/p&gt;


	&lt;h2&gt;RESTful routing&lt;/h2&gt;


	&lt;p&gt;Routing is connects URLs to code and also guides the basic controller structures of the application.  Sticking with the recommended controller actions and nesting resources properly really cleans up a given application, making it more consistent and logical, and allows the easy construction of machine-accessible APIs.  A good intro to RESTful routing is available on &lt;a href=&quot;http://darynholmes.wordpress.com/2008/03/15/beginners-tutorial-routing-in-rails-20-with-rest-part-1-of-n/&quot;&gt;Daryn Holmes&#8217; blog&lt;/a&gt; and there&#8217;s another good intro in the &lt;a href=&quot;http://guides.rubyonrails.org/routing.html&quot;&gt;Rails guides&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Test-first development&lt;/h2&gt;


	&lt;p&gt;We&#8217;ve decided to settle on the &lt;a href=&quot;http://github.com/thoughtbot/shoulda&quot;&gt;Shoulda&lt;/a&gt;  gem (in conjunction with Test::Unit) for unit and functional tests. From all the different testing frameworks we&#8217;ve tried out, it is the simplest and most readable way of ending up with a comprehensive test suite.  There&#8217;s a great screencast on how to use Shoulda &lt;a href=&quot;http://mtnwestrubyconf2008.confreaks.com/12saleh.html&quot;&gt;here&lt;/a&gt; We&#8217;ve also settled on using the Machinist gem instead of fixtures: http://github.com/notahat/machinist.  For small projects, fixtures are fine.  For anything with a complex domain model, fixtures start to suck pretty quickly.&lt;/p&gt;


	&lt;p&gt;In order to generate our models, controllers, and scaffolds using the Test::Unit/Shoulda/Machinist stack, and get 100% test coverage on the scaffolds out of the box, we built our own gem which does the boring work for us: the &lt;a href=&quot;http://github.com/futurechimp/shoulda_machinist_generator&quot;&gt;shoulda_machinist_generator&lt;/a&gt;.  Check it out :).&lt;/p&gt;


	&lt;h2&gt;Activerecord (especially associations)&lt;/h2&gt;


	&lt;p&gt;Reading and understanding pretty much the entirety of the &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Base.html&quot;&gt;ActiveRecord&lt;/a&gt;  documentation is extremely important.  Busting out of ActiveRecord and using raw &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; when necessary is still smart &#8211; but the point at which that happens should be pretty far up the complexity mountain, it shouldn&#8217;t be a first resort when doing rapid development.  For optimization, yes;  for doing extremely complex queries, yes; for doing basic has_many, has_many :through, has_one, or polymorphic queries, no.  New Rails coders often seem to have trouble breaking out of a database-table-centric mentality, especially when it comes to associations &#8211; so read the &lt;a href=&quot;http://guides.rubyonrails.org/association_basics.html&quot;&gt;basics&lt;/a&gt; about the &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html&quot;&gt;ActiveRecord class methods&lt;/a&gt;.  Every day when you wake up, repeat the phrase &lt;em&gt;in Ruby, everything is an object, so I should stop doing things like &#8220;validates_presence_of :article_id&#8221;&lt;/em&gt;.&lt;/p&gt;


	&lt;h2&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;The temptation to use the &#8220;old standby&#8221; &lt;span class=&quot;caps&quot;&gt;CTRL&lt;/span&gt;-C, &lt;span class=&quot;caps&quot;&gt;CTRL&lt;/span&gt;-V when building new functionality is always hard to avoid.  Using test-first development is one way to fight this evil urge, another way is the rule of threes: writing code once is good, copying and pasting it into another part of the application is alright but not desirable, and if you find yourself copying and pasting it into a third place then you probably need to do some refactoring.  Since all the code should be tested, refactoring should be easy because of the big testing safety-net.  Keep it &lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;: &lt;a href=&quot;http://en.wikipedia.org/wiki/Don%27t_repeat_yourself&quot;&gt;don&#8217;t repeat yourself&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;These are the basics of Rails development &#8211; once these are in place and working, it&#8217;s time to start configuring continuous integration servers (we use &lt;a href=&quot;http://github.com/thoughtworks/cruisecontrol.rb&quot;&gt;CruiseControl.rb&lt;/a&gt;), &lt;a href=&quot;http://eigenclass.org/hiki.rb?rcov&quot;&gt;rcov&lt;/a&gt; for test coverage metrics, and figuring out how to deploy using &lt;a href=&quot;http://capify.org&quot;&gt;Capistrano&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;It&#8217;s interesting to note just how much the whole Rails ecosystem has grown. For someone moving across from a different environment (PHP, .NET or Java), Rails is no longer the lightweight framework that we used to know and love when we started with it.  The core workflow has stayed pretty much the same &#8211; code generation does what it always did, ActiveRecord still makes us happy, etc.  But the amount of problems that people are solving in the wider Ruby and Rails ecosystem means that it&#8217;s possible to do amazing things quickly, if only you know where to look.  Our own &lt;a href=&quot;http://github.com/futurechimp/branston&quot;&gt;Branston gem&lt;/a&gt; is a good example of this &#8211; it solves a set of problems that advanced Rails users do have (automatic generation of Cucumber acceptance-test code) but which new users probably don&#8217;t need to know about.  Wading through the blog swamp is hard work &#8211; anybody else have any Rails duckboards to help newcomers?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-01-19:32</id>
    <published>2010-01-19T14:54:00Z</published>
    <updated>2010-02-01T16:17:53Z</updated>
    <category term="Essays"/>
    <category term="cloud"/>
    <category term="distributed computation"/>
    <category term="essay"/>
    <category term="on-demand"/>
    <category term="parallel"/>
    <category term="services"/>
    <category term="virtualization"/>
    <link href="http://futurechimp.org/2010/1/19/unclouding-the-cloud-some-conceptual-tools" rel="alternate" type="text/html"/>
    <title>Demystifying the Cloud</title>
<content type="html">
            &lt;p&gt;I don&#8217;t like talking about &#8220;the cloud&#8221; for the same reason I don&#8217;t like talking about &#8220;web 2.0&#8221; &#8211; although it&#8217;s suggestive of a certain set of ideas, it&#8217;s too vague to really do anything creative with. I figure anybody who can talk about &#8220;the cloud&#8221; for more than 30 seconds without mentioning more specific technologies is thinking at a much too general level.&lt;/p&gt;


	&lt;p&gt;Whether I&#8217;m right or wrong about that, there are a lot of people gasbagging about &#8220;the cloud&#8221; just now. Let&#8217;s take a few steps back and think about applying the level of detail implied by such a non-specific phrase to stuff that isn&#8217;t software. Duke Ellington wouldn&#8217;t write a jazz tune by thinking about &#8220;woodwind instruments&#8221; &#8211; he&#8217;d do it by thinking something like &#8220;what kind of song structure would really allow Johnny Hodges to let it rip? What key should I write it in? What should the drummer do?&#8221;.  Although there&#8217;s no evidence to support my claim, I doubt that Leonardo Da Vinci got anything useful out of thinking about anything as general as &#8220;oil painting&#8221;, even though that was the hot new thing at the time.&lt;/p&gt;


	&lt;p&gt;Anyone who&#8217;s serious about being creative and making cool stuff needs to think seriously about the conceptual and technical tools which they have at their disposal, and overly-generalized marketing buzzwords only get in the way of this kind of thinking. It doesn&#8217;t matter whether you&#8217;re making music, painting, writing code, or writing a novel, without clear thinking about what you&#8217;re trying to do and how to achieve it, you&#8217;re just going to make a mess.&lt;/p&gt;


	&lt;h2&gt;Some conceptual tools&lt;/h2&gt;


	&lt;p&gt;So what are people talking about when they talk about &#8220;the cloud&#8221;?  Let&#8217;s try and break it down, because there are some interesting ideas in there.&lt;/p&gt;


	&lt;p&gt;A common breakdown of the cloud is to think of it as being made up of the following categories:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Software as a Service&lt;/li&gt;
		&lt;li&gt;Platform as a Service&lt;/li&gt;
		&lt;li&gt;Utility Computing&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;This categorization scheme is focused on marketing concerns rather than technical and creative ones, and it doesn&#8217;t do much to help me think about cool stuff I could build.  I prefer a categorization that looks more like this:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;On-demand services&lt;/strong&gt; &#8211; You only pay for the computing power you use, and the costs of both entry and exit are low (although the running costs may be significantly higher on a per-unit basis than for &#8220;normal&#8221; systems).  Capital costs are borne by the service provider.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Virtualization&lt;/strong&gt; &#8211; Running your systems inside a software container instead of running it directly on physical hardware. This could mean virtualizing the entire operating system or virtualizing an application in a sandbox or VM.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Parallel processing&lt;/strong&gt; &#8211; Using networked computers as one big computer to solve computationally expensive problems more quickly, also known as &#8220;grid computing&#8221;.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Distributed architectures&lt;/strong&gt; &#8211; Linking a bunch of machines together on a network and setting up applications that run across multiple machines.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Self-managing systems&lt;/strong&gt; &#8211; Software systems that are designed to take intelligent actions based on what&#8217;s happening in their environment.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;These concepts are like Lego blocks.  We can chain them together to make interesting software systems, depending on what we want to achieve.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://aws.amazon.com/ec2/&quot;&gt;Amazon&#8217;s &lt;span class=&quot;caps&quot;&gt;EC2&lt;/span&gt;&lt;/a&gt;, for example, is basically &lt;strong&gt;on-demand services&lt;/strong&gt; + &lt;strong&gt;operating system virtualization&lt;/strong&gt;.  Once we&#8217;ve got those two blocks snapped together, we&#8217;ve got a very interesting base to work from.  We could be content with on-demand virtualization and use it to just deal with traffic spikes without massive capital investment, or we could snap a few more concepts into place.&lt;/p&gt;


	&lt;p&gt;On-demand virtualized operating systems + distributed architectures when applied to the problem of storage equals a virtual Storage Area Network which can store petabytes of information.  Examples of this in the real world are things like &lt;a href=&quot;http://aws.amazon.com/s3/&quot;&gt;Amazon S3&lt;/a&gt; or &lt;a href=&quot;https://one.ubuntu.com/&quot;&gt;Ubuntu One&lt;/a&gt;.  I&#8217;m currently experimenting with a system that&#8217;s in the same general category, a CouchDB-based network-storage system called &lt;a href=&quot;http://github.com/futurechimp/adhd&quot;&gt;adhd&lt;/a&gt; which I&#8217;m working on with a friend. It adds the concept of self-management and can make its own semi-intelligent decisions about replication, although it&#8217;s still very much a work in progress.&lt;/p&gt;


	&lt;p&gt;Sometimes it&#8217;s interesting to take a Lego block away (instead of adding one) and see what happens.  Thinking about distributed architectures and parallel processing without OS virtualization, for example, is interesting to me when I consider that even a relatively poor neighbourhood of London like the one I live in (Brixton/Stockwell) probably has more spare processing cycles in peoples&#8217; houses than many data centres.  This is a computing issue (what could we build if we could harness that processing power?) but it&#8217;s also a social and environmental issue (it&#8217;s wasteful to have all those machines sitting idle).&lt;/p&gt;


	&lt;p&gt;One thing which probably isn&#8217;t in anybody&#8217;s &#8220;cloud&#8221; categorization, but which I&#8217;m interested in, is the notion of event-driven systems.  Polling sucks, and we should be building systems that can notify other systems when something happens, instead of repeatedly asking &#8220;has this thing happened yet?&#8221;.  Google&#8217;s pubsubhubbub protocol is an interesting attempt to apply an event-driven approach to &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed publish notifications.  Any time we can use events instead of polling, we should.  Eventually we&#8217;ll hit a point where polling systems are seen for the slow, primitive beasts they are, and we&#8217;ll have a real-time internet. Until then, setTimeout() and &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; polling will continue to rule the internetz.&lt;/p&gt;


	&lt;p&gt;If these are the basic suppositions, what tools are going to grow in importance and what kinds of systems are we going to see in the next little while?  What are the implications for the popular tools of today?&lt;/p&gt;


	&lt;h2&gt;Technical Tools&lt;/h2&gt;


	&lt;p&gt;The increased ease of operating system virtualization could make application virtualization and portability a lot less compelling. Who cares if Java can run on every possible machine architecture and operating system, if we can virtualize operating systems and specific applications really easily?&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://php.net&quot;&gt;&lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt;&lt;/a&gt; will either get a decent threading model or die &#8211; too many of our Lego blocks rely on the idea that a language runtime can walk and chew gum at the same time, or at least fake it convincingly, and &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt;&#8217;s approach (fork an entirely new operating system process) just won&#8217;t cut it much longer.  Java, the .NET languages, and the dynamic duo (Python and Ruby) won&#8217;t be hurt by this.  With Ruby specifically, the &lt;a href=&quot;http://jruby.org/&quot;&gt;JRuby&lt;/a&gt; implementation is going to keep rising in popularity since it&#8217;s got Java&#8217;s tried-and-tested concurrency code going for it and doesn&#8217;t have the Global Interpreter Lock (GIL) that &lt;span class=&quot;caps&quot;&gt;MRI 1&lt;/span&gt;.8 and 1.9 have. For the kinds of multi-threaded distributed systems I&#8217;m talking about, &lt;a href=&quot;http://ftp.sunet.se/pub/lang/erlang/&quot;&gt;Erlang&lt;/a&gt; and &lt;a href=&quot;http://www.scala-lang.org/&quot;&gt;Scala&lt;/a&gt; seem like they can only grow in popularity, seeing as how they were designed to deal with exactly this problem set. Lastly, for persistence, distributed block storage systems and the &lt;a href=&quot;http://en.wikipedia.org/wiki/NoSQL&quot;&gt;NoSQL&lt;/a&gt; movement are going to be increasingly important.&lt;/p&gt;


	&lt;p&gt;Proprietary vendors will need to come up with a compelling license-management story for on-demand services or risk being bypassed by a whole generation of geeks who can&#8217;t be bothered to keep track of what licenses they&#8217;ve used. So far the massive first-mover advantage of Amazon in the virtualized on-demand operating system space, built largely on a Free Software stack (Xen and Linux), has obscured this.&lt;/p&gt;


	&lt;p&gt;If I want to set up my own OS virtualization and app infrastructure based on technologies which require license payments, and I want to bring instances up and down 300 times a month, how many licenses have I used?  How much hassle will it be for me to keep track of? Why should I bother?  Proprietary software vendors can mitigate this problem to some extent by cutting deals with hosting companies and getting them to take care of the bean-counting at a layer below that of the app developer.&lt;/p&gt;


	&lt;h2&gt;The world&#8217;s biggest existing &#8220;cloud&#8221;?&lt;/h2&gt;


	&lt;p&gt;Turning from tools to stuff we can build, what sorts of things are possible if we try snapping some of our conceptual Lego blocks together in different ways?  Well, let&#8217;s take a look at the largest cloud system that everyone ignores. Sometimes people snap the conceptual Lego together in some pretty interesting ways, and it&#8217;s worth paying attention when they do.&lt;/p&gt;


	&lt;p&gt;&lt;/p&gt;


	&lt;p&gt;The biggest publicly-accessible redundant storage system on the planet is one which we don&#8217;t normally think of as being a &#8220;cloud&#8221; system: the global Bittorrent network.  This system uses a mix of &lt;strong&gt;on-demand services&lt;/strong&gt;, a &lt;strong&gt;distributed storage and addressing infrastructure&lt;/strong&gt;, and &lt;strong&gt;software self-management&lt;/strong&gt; to swap movies and music, and back it all up in a redundant system running on tens of millions of computers. It&#8217;s mostly ignored in the &#8220;legitimate&#8221; application development literature because the vast majority of the content inside the network infringes copyright law, but it&#8217;s an amazing system nonetheless.  To copyright owners, it&#8217;s a Frankenstein&#8217;s Monster which so far seems unkillable.&lt;/p&gt;


	&lt;p&gt;Compared to BitTorrent infrastructure, Amazon&#8217;s &lt;span class=&quot;caps&quot;&gt;EC2&lt;/span&gt; is a fairly miniscule system.  Realizing this made me think a bit about how snobby we programmers can be.  Despite a lot of rhetoric about &#8220;revolutionary&#8221; and &#8220;disruptive&#8221; technologies in blogs the world over, the fact that a bunch of 15 year old kids can distribute content more efficiently than the world&#8217;s largest media corporations mostly escapes our notice.  The technology that accounts for about half the world&#8217;s &lt;span class=&quot;caps&quot;&gt;TCP&lt;/span&gt;/IP traffic gets little mention from app development bloggers, because we&#8217;re all focused on Infrastructure as a Service discussions and flapping around with our iPhones.  To his credit George Reese does mention BitTorrent (once) in his book &lt;a href=&quot;http://oreilly.com/catalog/9780596156374&quot;&gt;Cloud Application Architectures&lt;/a&gt;.  It&#8217;d be interesting to see it get a mention in the software architecture literature. Ironically, the book &lt;a href=&quot;http://www.amazon.com/Essential-Software-Architecture-Ian-Gorton/dp/3540287132&quot;&gt;Essential Software Architecture&lt;/a&gt; is &lt;a href=&quot;http://extratorrent.com/torrent/1434323/Essential+Software+Architecture.html&quot;&gt;available as a torrent&lt;/a&gt; but doesn&#8217;t mention BitTorrent.&lt;/p&gt;


	&lt;h2&gt;Some experiments&lt;/h2&gt;


	&lt;p&gt;Despite all the hype about it, all of this cloud-related stuff is actually one of the most interesting things to happen in the last three years.  Getting in on the game, me and my friend &lt;a href=&quot;http://github.com/manossim&quot;&gt;Manos&lt;/a&gt; have been messing around with distributed storage architectures, on-demand services, and self-managing systems in our &lt;a href=&quot;http://github.com/futurechimp/adhd&quot;&gt;adhd&lt;/a&gt; project.  Even though it doesn&#8217;t really do enough yet to be useful, the sheer fun and challenge of building such a weird system (using &lt;a href=&quot;http://couchdb.apache.org&quot;&gt;CouchDB&lt;/a&gt; on top of an &lt;a href=&quot;http://rubyeventmachine.com&quot;&gt;Eventmachine&lt;/a&gt; base) has been a blast.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve also been building a little distributed video encoder called the &lt;a href=&quot;http://github.com/futurechimp/enigmamachine&quot;&gt;Enigmamachine&lt;/a&gt; (again using Eventmachine as a base, but this time with &lt;a href=&quot;http://sinatrarb.com&quot;&gt;Sinatra&lt;/a&gt; in a supporting role).  There&#8217;s a whole area of programming just waiting to be explored.  While none of this stuff is new (all of the stuff on our &#8220;Cloud Lego&#8221; list has been part of the programmer&#8217;s toolbox for decades), it does seem that the pervasiveness of &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; and the mass availability of high-bandwith networks is opening up a lot of new prospects.&lt;/p&gt;


	&lt;p&gt;I&#8217;ll be giving a talk about all of this stuff at a &lt;a href=&quot;http://www.bima.co.uk/events/050B000506081C16050A01/virtualisation---get-with-the-virtualisation-revolution/&quot;&gt;British Interactive Media Association&lt;/a&gt; event at the swanky &lt;a href=&quot;http://www.thehospitalclub.com/&quot;&gt;Hospital Club&lt;/a&gt; (the guys over at &lt;a href=&quot;http://ultraspeed.co.uk&quot;&gt;Ultraspeed&lt;/a&gt; invited me, thanks for that!).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-01-17:31</id>
    <published>2010-01-17T17:47:00Z</published>
    <updated>2010-01-17T18:36:31Z</updated>
    <category term="enigmamachine"/>
    <category term="eventmachine"/>
    <category term="procs"/>
    <category term="ruby"/>
    <category term="sinatra"/>
    <category term="thin"/>
    <link href="http://futurechimp.org/2010/1/17/ruby-procs-and-eventmachine-callbacks" rel="alternate" type="text/html"/>
    <title>Ruby Procs and Eventmachine callbacks</title>
<content type="html">
            &lt;p&gt;For the last little while, I&#8217;ve been messing around to see whether I can whip off a video-encoding server which is easily installable.  It&#8217;s put together using &lt;a href=&quot;http://sinatrarb.org&quot;&gt;Sinatra&lt;/a&gt;, &lt;a href=&quot;http://code.macournoyer.com/thin/&quot;&gt;Thin&lt;/a&gt;, and &lt;a href=&quot;http://rubyeventmachine.com/&quot;&gt;Eventmachine&lt;/a&gt; (three of my favourite Ruby libraries lately).&lt;/p&gt;


	&lt;p&gt;At the point where it all started to work, I ran into a nasty order-of-operations problem.  To fix it, I had to do a little research into how Ruby sets up blocks and procs.&lt;/p&gt;


	&lt;p&gt;The basic system is fairly simple.  There&#8217;s a web interface written in Sinatra, which runs inside Thin.  Off to the side of this running webapp is an Eventmachine process sitting around waiting to encode videos.  The webapp interface allows users to easily define encoder profiles, which are sets of tasks for ffmpeg.  As an example, we might define an Encoder with three EncodingTask objects attached to it:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;output to 320&#215;240 flash video&lt;/li&gt;
		&lt;li&gt;output to 720&#215;576 ogg theora&lt;/li&gt;
		&lt;li&gt;make a 320&#215;240 thumbnail jpg.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;When this Encoder is applied to a new video, the tasks are run in order on the video.  Once there are no more tasks, the video state is changed to &#8220;complete&#8221;.&lt;/p&gt;


	&lt;p&gt;The code that accomplishes this is pretty simple, except for the fact that it&#8217;s multithreaded:&lt;/p&gt;


&lt;pre&gt;
  def ffmpeg(task, video)
    command_string = &quot;ffmpeg -i #{video.file} #{task.command} #{video.file + task.output_file_suffix}&quot; 
    encoding_operation = proc {
      video.state = &quot;encoding&quot; 
      video.save
      Log.info(&quot;Executing: #{task.name}&quot;)
      `nice -n 19 #{command_string}`
    }
    completion_callback = proc {|result|
      if task == encoding_tasks.last
        video.state = &quot;complete&quot; 
        video.save
      else
        current_task_index = encoding_tasks.index(task)
        next_task_index = current_task_index + 1
        next_task = encoding_tasks[next_task_index]
        ffmpeg(next_task, video)
      end
    }
    EventMachine.defer(encoding_operation, completion_callback)
  end
&lt;/pre&gt;

	&lt;p&gt;The first time through, the code is called with the first EncodingTask and whatever video is being encoded.  The method then calls itself again for every EncodingTask until there are no more EncodingTasks left in the queue, at which point the video is marked as complete and everything chills out.  The main motivations for this code are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;We need to execute a long-running, blocking process (the ffmpeg encoding)&lt;/li&gt;
		&lt;li&gt;We want the Sinatra/Thin application to keep running while we&#8217;re encoding, because we want to be able to queue up other videos to encode&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The &lt;a href=&quot;http://eventmachine.rubyforge.org/EventMachine.html#M000486&quot;&gt;EventMachine.defer&lt;/a&gt; method does what we need here.  EventMachine is mainly designed to be &lt;a href=&quot;http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/&quot;&gt;blindingly fast&lt;/a&gt; for network operations by using a single-threaded evented reactor loop, but the single-threaded approach only works in cases where non-blocking processing is being done.  For blocking I/O, like the call to ffmpeg here, EventMachine.defer comes to the rescue for us:  by default, EventMachine sets up a pool of 20 ruby threads which are available for use by EventMachine.defer in cases where it&#8217;s really necessary to use multiple ruby threads.&lt;/p&gt;


	&lt;p&gt;Don&#8217;t confuse EventMachine.defer with &lt;a href=&quot;http://eventmachine.rubyforge.org/EventMachine/Deferrable.html&quot;&gt;EventMachine Deferrables&lt;/a&gt;, which are related to the single-threaded part of EventMachine.  EM.defer is a method which takes two proc objects as its arguments &#8211; the first should contain your long-running operation, the second is a callback which should be executed once the long-running operation is completed.  The main problem with my code above is that it didn&#8217;t work.&lt;/p&gt;


	&lt;p&gt;I naively expected that I could set the local variable &lt;code&gt;current_task_index&lt;/code&gt; inside my &lt;code&gt;completion_callback&lt;/code&gt; proc and use it normally.  This was a really dumb thing to do, as I realized once I did a little refresher research into Proc objects and how they work in Ruby.&lt;/p&gt;


	&lt;p&gt;Procs get their variables from their surrounding scope when they are defined, &lt;strong&gt;not&lt;/strong&gt; when they are called.  This led to all kinds of exciting order-of-operations bugs in my code, which was all speedily fixed once I moved the &lt;code&gt;current_task_index = encoding_tasks.index(task)&lt;/code&gt; line so that it was the first thing defined in the method.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2010-01-05:30</id>
    <published>2010-01-05T12:33:00Z</published>
    <updated>2010-01-05T12:37:32Z</updated>
    <category term="autotest"/>
    <category term="rails"/>
    <category term="redgreen"/>
    <category term="testing"/>
    <link href="http://futurechimp.org/2010/1/5/setting-up-autotest-rails-redgreen-and-cucumber" rel="alternate" type="text/html"/>
    <title>Setting up autotest, rails, redgreen, and cucumber</title>
<content type="html">
            &lt;p&gt;Time for another brain-externalizing post to remind myself how things work when setting up new systems.  The basic process for setting up a Rails environment with exciting testing goodness is:&lt;/p&gt;


&lt;pre&gt;sudo gem install ZenTest autotest-rails redgreen&lt;/pre&gt;

	&lt;p&gt;Then in your home directory, make a .autotest file containing:&lt;/p&gt;


&lt;pre&gt;require 'redgreen/autotest'&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2009-11-23:29</id>
    <published>2009-11-23T16:33:00Z</published>
    <updated>2009-11-23T16:38:01Z</updated>
    <category term="backtrace cleaner"/>
    <category term="rails"/>
    <category term="stacktrace"/>
    <category term="testunit"/>
    <link href="http://futurechimp.org/2009/11/23/the-rails-backtrace-cleaner" rel="alternate" type="text/html"/>
    <title>The Rails Backtrace cleaner</title>
<content type="html">
            &lt;p&gt;I&#8217;d missed it, but Rails now incorporates the functionality previously provided by Thoughtbot&#8217;s &lt;a href=&quot;http://robots.thoughtbot.com/post/159807521/shhh-your-test-unit-backtraces-are-too-noisy&quot;&gt;quietbacktrace&lt;/a&gt; gem.  It&#8217;s pretty easy to use, too. By default, it whacks all of the stacktrace garbage that used to happen in a Rails 2.2 app. It&#8217;s also possible to easily add new filters in your test_helper.rb file, e.g.&lt;/p&gt;


&lt;pre&gt;
  # Add more helper methods to be used by all tests here...
  #
  Rails.backtrace_cleaner.add_silencer { |line| line =~ /lib\/shoulda/ }
&lt;/pre&gt;

	&lt;p&gt;Artificially inducing a test failure then gives a beautiful little stack trace, like so:&lt;/p&gt;


&lt;pre&gt;
  1) Failure:
test: the JobsController should get new. (JobsControllerTest) [/test/functional/jobs_controller_test.rb:19]:
Expected response to be a &amp;lt;:successsadfsdaf&amp;gt;, but was &amp;lt;200&amp;gt;
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://futurechimp.org/">
    <author>
      <name>dave</name>
    </author>
    <id>tag:futurechimp.org,2009-11-20:28</id>
    <published>2009-11-20T10:38:00Z</published>
    <updated>2009-12-07T12:23:02Z</updated>
    <category term="karmic"/>
    <category term="koala"/>
    <category term="qct"/>
    <category term="svn 1.6"/>
    <category term="ubuntu"/>
    <link href="http://futurechimp.org/2009/11/20/qct-back-in-action" rel="alternate" type="text/html"/>
    <title>QCT - Back in Action</title>
<content type="html">
            &lt;p&gt;Ubuntu releases with broken versions of the &lt;span class=&quot;caps&quot;&gt;QCT&lt;/span&gt; Commit Tool appear to be something of a tradition, and Ubuntu 9.10 (Karmic Koala) is no exception.  Qct is an easy to use, very lightweight commit tool which I always find myself reaching for when doing commits these days, and I go a bit mental when I need to use subversion and it&#8217;s not around.  Anway, to the problem:&lt;/p&gt;


&lt;pre&gt;
chimp@boomer:~/workspace/projectname $ qct
Auto-detected Subversion repository
&lt;/pre&gt;

	&lt;p&gt;Qct fires up, I type in a commit message, and select which files I want to commit.  Everything looks good until we hit the &#8220;commit&#8221; button:&lt;/p&gt;


&lt;pre&gt;
Error code 1 not expected
Traceback (most recent call last):
  File &quot;/usr/lib/pymodules/python2.6/qctlib/gui_logic.py&quot;, line 801, in commitSelected
    self.vcs.commitFiles(checkedItemList, msg)
  File &quot;/usr/lib/pymodules/python2.6/qctlib/vcs/svn.py&quot;, line 231, in commitFiles
    runProgram([self.svn_exe, 'commit', '-F', filename] + commitFileNames)
  File &quot;/usr/lib/pymodules/python2.6/qctlib/utils.py&quot;, line 143, in runProgram
    raise ProgramError(progStr, out)
qctlib.utils.ProgramError: svn commit -F /tmp/tmpChpKyU  app/controllers/application_controller.rb: svn: '/home/chimp/workspace/projectname/ app/controllers' is not a working copy
svn: '/home/chimp/workspace/projectname/ app/controllers' does not exist
&lt;/pre&gt;

	&lt;p&gt;Note the space between &lt;strong&gt;projectname&lt;/strong&gt; and &lt;strong&gt;app&lt;/strong&gt;.  An older version of qct is not loving the new subversion 1.6 in Ubuntu, which brings some new options with it.  Ok, time for the source tarball off of http://qct.sourceforge.net.  To compile it, you&#8217;ll need to &lt;code&gt;sudo apt-get install pyqt4-dev-tools&lt;/code&gt;, then &lt;code&gt;cd&lt;/code&gt; into the source directory and run &lt;code&gt;sudo make site-install&lt;/code&gt; to install it system-wide.  Did you do that?  Bad news for not reading ahead, because attempting to use &lt;em&gt;that&lt;/em&gt; &lt;code&gt;qct&lt;/code&gt; binary gets  you:&lt;/p&gt;


&lt;pre&gt;
chimp@boomer:~/workspace/projectname$ qct
Traceback (most recent call last):
  File &quot;/usr/local/bin/qct&quot;, line 13, in &amp;lt;module&amp;gt;
    from qctlib.gui_logic import CommitTool
  File &quot;/usr/local/lib/python2.6/dist-packages/qctlib/gui_logic.py&quot;, line 9, in &amp;lt;module&amp;gt;
    from qctlib.ui_dialog import Ui_commitToolDialog
ImportError: cannot import name Ui_commitToolDialog
&lt;/pre&gt;

	&lt;p&gt;So, that one doesn&#8217;t even fire up.&lt;/p&gt;


	&lt;p&gt;Lastly, I grabbed the latest source for the project:&lt;/p&gt;


&lt;pre&gt;
sudo apt-get install mercurial  pyqt4-dev-tools
hg clone http://bitbucket.org/sborho/qct/
cd qct
sudo make site-install
&lt;/pre&gt;

	&lt;p&gt;Don&#8217;t forget to &lt;code&gt;apt-get install pyqt4-dev-tools&lt;/code&gt; first, or that&#8217;ll blow.&lt;/p&gt;


	&lt;p&gt;The latest source appears to work fine, very many thanks to the author &lt;a href=&quot;http://borho.org&quot;&gt;Steve Borho&lt;/a&gt; for this great little tool.&lt;/p&gt;
          </content>  </entry>
</feed>

