<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Adam Taylor &#187; Code</title>
	<atom:link href="http://www.adamjctaylor.com/category/code/feed" rel="self" type="application/rss+xml" />
	<link>http://www.adamjctaylor.com</link>
	<description>Software Engineering, Marketing &#38; Business.</description>
	<lastBuildDate>Tue, 18 May 2010 11:52:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0-beta1</generator>
		<item>
		<title>Perl Ain&#8217;t Dead&#8230;</title>
		<link>http://www.adamjctaylor.com/perl-aint-dead</link>
		<comments>http://www.adamjctaylor.com/perl-aint-dead#comments</comments>
		<pubDate>Wed, 03 Mar 2010 18:18:53 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=683</guid>
		<description><![CDATA[I just stumbled across this whole other Perl eco-system I wasn&#8217;t aware existed, which is very much a mirror of the exciting/interesting things going on in Ruby/Python land. I tend to hear a lot about Ruby, and less about Perl, from hacker news and other places so I hadn&#8217;t seen any of this new Perl [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I just stumbled across this whole other Perl eco-system I wasn&#8217;t aware existed, which is very much a mirror of the exciting/interesting things going on in Ruby/Python land.</p>
<p>I tend to hear a lot about Ruby, and less about Perl, from <a href="http://news.ycombinator.com">hacker news</a> and other places so I hadn&#8217;t seen any of this new Perl stuff.</p>
<p>I absolutely love <a href="http://www.sinatrarb.com">Sinatra</a> (a micro Ruby web DSL) but it turns out there is a perl port &#8211; <a href="http://dancer.sukria.net/">Dancer</a>!  I haven&#8217;t had a chance to try it out yet but plan to ASAP.</p>
<p><span id="more-683"></span></p>
<p>Also, in Ruby land there is this whole <a href="http://rack.rubyforge.org/">RACK</a> middleware layer thing which &#8220;provides a minimal interface between webservers supporting Ruby and Ruby frameworks.&#8221;  </p>
<p>Well, turns out Perl has its own version to: <a href="http://plackperl.org/">PLACK</a>.  Exciting times!</p>
<p>Also, in Ruby land are a number of high performance application servers, <a href="http://code.macournoyer.com/thin/">Thin</a> and <a href="http://unicorn.bogomips.org/">Unicorn</a> being two.  Well guess what?  We&#8217;ve got them too&#8230;!</p>
<p><a href="http://github.com/miyagawa/Twiggy">Twiggy</a> and <a href="http://github.com/miyagawa/Starman">Starman</a> respectively.</p>
<p>I&#8217;d quite like to set up a little nginx proxying -> starman environment, with an application written in Dancer (or Catalyst).</p>
<p>Not only are there all these new HTTP based projects there&#8217;s a new cpan module installer &#8211; <a href="http://github.com/miyagawa/cpanminus">cpanminus</a> &#8211; which has had some <a href="http://marcus.nordaaker.com/2010/02/cpanminus-the-new-cpan-superstar/">rave</a> <a href="http://www.dagolden.com/index.php/689/the-power-of-not-being-all-things-to-all-people/">reviews</a>.</p>
<p>These are exciting times to be involved in the Perl community.  The <a href="http://bit.ly/aj2P8B">Catalyst Book</a> [aff] is an excellent reference manual about modern Perl web development and the up-coming <a href="http://www.modernperlbooks.com/">Modern Perl Book</a> promises to be equally enlightening.</p>
<p>Perhaps someone could implement <a href="http://rvm.beginrescueend.com/">rvm</a> [oops fixed] for Perl, then I could easily try out the various Perl 5.x updates, or I should at least learn to use <a href="http://search.cpan.org/~apeiron/local-lib-1.004009/lib/local/lib.pm">Local::Lib</a>.</p>
<p>Honestly, I&#8217;m excited, stick around! Perl isn&#8217;t going anywhere&#8230;</p>
<p>[This was quite a rambling, whirl-wind tour of new Perl projects, that I've literally only just stumbled across.  <a href="http://feeds.feedburner.com/adamjctaylor/asdf">Subscribe</a> [RSS] to find out more as I try them out for real over the next short while&#8230;].</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/become-a-perl-rockstar' rel='bookmark' title='Permanent Link: Become a Perl rockstar&#8230; AKA Perl link dump'>Become a Perl rockstar&#8230; AKA Perl link dump</a></li><li><a href='http://www.adamjctaylor.com/open-melody-homebrew-and-catalyst-mojo' rel='bookmark' title='Permanent Link: Open Melody, Homebrew, Catalyst/Mojo and Sinatra.'>Open Melody, Homebrew, Catalyst/Mojo and Sinatra.</a></li><li><a href='http://www.adamjctaylor.com/mad-lib-perl-snippet' rel='bookmark' title='Permanent Link: Mad-Lib Perl Snippet'>Mad-Lib Perl Snippet</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/perl-aint-dead/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Shwartzian Transform</title>
		<link>http://www.adamjctaylor.com/shwartzian-transform</link>
		<comments>http://www.adamjctaylor.com/shwartzian-transform#comments</comments>
		<pubDate>Thu, 24 Dec 2009 03:42:51 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=360</guid>
		<description><![CDATA[I was trying to merge sort a list of files based on their last modified date when someone said to me &#8220;do a schwartzian&#8221;. Now, I had no idea what they were talking about so off to google I went. It&#8217;s basically this (shamelessly ripped from the excellent Wikipedia article): @sorted = map { $_->[0] [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I was trying to merge sort a list of files based on their last modified date when someone said to me &#8220;do a schwartzian&#8221;.  Now, I had no idea what they were talking about so off to google I went.</p>
<p>It&#8217;s basically this (shamelessly ripped from the <a href="http://en.wikipedia.org/wiki/Schwartzian_transform" rel="nofollow">excellent Wikipedia article</a>):</p>
<p><span id="more-360"></span></p>
<blockquote><pre>
@sorted = map  { $_->[0] }
                  sort   { $a->[1] cmp $b->[1] }
                  map  { [$_, foo($_)] }
                           @unsorted;
</pre>
<p>Reading from right to left (or from the bottom to the top):</p>
<ul>
<li>the original list @unsorted is fed into a map operation that wraps each item into a (reference to an anonymous 2-element) array consisting of itself and the calculated value that will determine its sort order (list of item becomes a list of [item=>value]);</li>
<li>then the list of lists produced by map is fed into sort, which sorts it according to the values previously calculated (list of [item, value] => sorted list of [item, value]);</li>
<li>finally, another map operation unwraps the values (from the anonymous array) used for the sorting, producing the items of the original list in the sorted order (sorted list of [item, value] => sorted list of item).</li>
</ul>
<p>The use of anonymous arrays ensures that memory will be reclaimed by the Perl garbage collector immediately after the sorting is done.</p>
<p>The computational savings obtained by the Schwartzian transform depend strongly on the structure of the inner function. For an efficient ordinary sort function, the number of invocations of the transform function goes from an average of 2nlogn to n; one should carefully consider on a case-by-case basis whether the extra implementation complexity is justified by this efficiency saving.</p></blockquote>
<p>It&#8217;s worth noting that <code>foo()</code> is a method that returns the value that an element will be sorted against and that <code>$a</code> and <code>$b</code> are special Perl variables that you can read more about in the <a href="http://perldoc.perl.org/functions/sort.html">sort documentation</a>.</p>
<p>Pretty neat!</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/mad-lib-perl-snippet' rel='bookmark' title='Permanent Link: Mad-Lib Perl Snippet'>Mad-Lib Perl Snippet</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/shwartzian-transform/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tweetfactor &#8211; An experiment using Ruby, Sinatra, Twitter and Redis</title>
		<link>http://www.adamjctaylor.com/tweetfactor-an-experiment-using-ruby-sinatra-twitter-and-redis</link>
		<comments>http://www.adamjctaylor.com/tweetfactor-an-experiment-using-ruby-sinatra-twitter-and-redis#comments</comments>
		<pubDate>Tue, 08 Dec 2009 21:42:23 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=456</guid>
		<description><![CDATA[I stumbled across a blog post by digitalhobbit about building a little Sinatra App on top of the Twitter Streaming API. I followed that guide and made the core of Tweetfactor a couple of weeks ago. Actually getting the thing deployed, however, was pretty involved for me, having never used Rack/Passenger/God etc. etc. So the [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I stumbled across a blog post by <a href="http://twitter.com/digitalhobbit">digitalhobbit</a> about building <a href="http://www.digitalhobbit.com/2009/11/08/building-a-twitter-filter-with-sinatra-redis-and-tweetstream/">a little Sinatra App on top of the Twitter Streaming API</a>.</p>
<p>I followed that guide and made the core of <a href="http://www.tweetfactor.co.uk">Tweetfactor</a> a couple of weeks ago.  Actually getting the thing deployed, however, was pretty involved for me, having never used Rack/Passenger/God etc. etc. </p>
<p><span id="more-456"></span></p>
<p>So the following are hopefully all the steps I took, and the appropriate config files to get stuff up and running:</p>
<ol>
<li>So first off, I didn&#8217;t even have anywhere to host this app so I signed up to a 256 VPS from <a href="http://www.webbynode.com">webbynode</a> and then created an Ubuntu Rails Ready Stack (basically a one click install for an Rails Ready Ubuntu system).</li>
<li>Then I added a user and setup SSH and pub/priv keys from my laptop to the VPS.</li>
<li>Then I installed <a href="capify.org/">Capistrano</a> &#8211; <code>sudo gem install capistrano</code> &#8211; for one click deploys of the app to the server.  My code is on github in a private repo, so you&#8217;ll probably have to look through the Capistrano docs to edit this to your needs:
<p><code><br />
#========================<br />
#CONFIG<br />
#========================<br />
default_run_options[:pty] = true<br />
set :application, "tweetfactor.co.uk"<br />
set :scm, :git<br />
set :git_enable_submodules, 1<br />
set :repository, "git@github.com:adamtaylor/Tweetfactor.git"<br />
set :branch, "master"<br />
set :ssh_options, { :forward_agent => true }<br />
set :stage, :production<br />
set :user, "xxxx"<br />
set :scm_passphrase, "xxxxxxx"<br />
set :use_sudo, false<br />
set :runner, "deploy"<br />
set :deploy_to, "/var/www/#{application}"<br />
set :app_server, :passenger<br />
set :domain, "www.tweetfactor.co.uk"<br />
#========================<br />
#ROLES<br />
#========================<br />
role :app, domain<br />
role :web, domain<br />
role :db, domain, :primary => true<br />
#========================<br />
#CUSTOM<br />
#========================<br />
namespace :deploy do<br />
task :start, :roles => :app do<br />
run "touch #{current_release}/tmp/restart.txt"<br />
end<br />
task :stop, :roles => :app do<br />
# Do nothing.<br />
end<br />
desc "Restart Application"<br />
task :restart, :roles => :app do<br />
run "touch #{current_release}/tmp/restart.txt"<br />
end<br />
end<br />
</code></p>
</li>
<li>Then I had to download god, for process monitoring: <code>sudo gem install god</code>.</li>
<li>When I setup my Rails Ready Stack I told it to use Ruby Enterprise Edition, which means that my gems were installed in a funny place which I had to add to my $PATH.</li>
<li>With the help of <a href="http://mylescarrick.com/articles/simple_delayed_job_with_god">this post</a> I wrote a god init.d script as follows:
<p><code><br />
#!/bin/sh</p>
<p>### BEGIN INIT INFO<br />
# Provides: god<br />
# Required-Start: $all<br />
# Required-Stop: $all<br />
# Default-Start: 2 3 4 5<br />
# Default-Stop: 0 1 6<br />
# Short-Description: God<br />
### END INIT INFO</p>
<p>NAME=god<br />
DESC=god</p>
<p>set -e</p>
<p># Make sure the binary and the config file are present before proceeding<br />
test -x /opt/ruby-enterprise/bin/god || exit 0</p>
<p># Create this file and put in a variable called GOD_CONFIG, pointing to<br />
# your God configuration file<br />
# test -f /etc/default/god &#038;&#038; . /etc/default/god<br />
# [ $GOD_CONFIG ] || exit 0</p>
<p>. /lib/lsb/init-functions</p>
<p>RETVAL=0</p>
<p>case "$1" in<br />
start)<br />
  echo -n "Starting $DESC: "<br />
  #/opt/ruby-enterprise/bin/god -c $GOD_CONFIG -P /var/run/god.pid -l /var/log/god.log<br />
  /opt/ruby-enterprise/bin/god -c /etc/default/god -P /var/run/god.pid -l /var/log/god.log<br />
  RETVAL=$?<br />
  echo "$NAME."<br />
  ;;<br />
stop)<br />
  echo -n "Stopping $DESC: "<br />
  kill `cat /var/run/god.pid`<br />
  RETVAL=$?<br />
  echo "$NAME."<br />
  ;;<br />
restart)<br />
  echo -n "Restarting $DESC: "<br />
  kill `cat /var/run/god.pid`<br />
  #/opt/ruby-enterprise/bin/god -c $GOD_CONFIG -P /var/run/god.pid -l /var/log/god.log<br />
  /opt/ruby-enterprise/bin/god -c /etc/default/god -P /var/run/god.pid -l /var/log/god.log<br />
  RETVAL=$?<br />
  echo "$NAME."<br />
  ;;<br />
status)<br />
  /opt/ruby-enterprise/bin/god status<br />
  RETVAL=$?<br />
  ;;<br />
*)<br />
  echo "Usage: god {start|stop|restart|status}"<br />
  exit 1<br />
  ;;<br />
esac</p>
<p>exit $RETVAL</p>
<p></code>
</li>
<li>Then I setup a god config file in /etc/default/god &#8211; it has some code duplication so could probably be improved but it seems to work none-the-less:
<p><code></p>
<p># run with: god -c /path/to/redis.god -D</p>
<p>God.watch do |w|<br />
    w.name = "redis-server"<br />
    w.interval = 30.seconds # default<br />
    w.start = "redis-server /var/www/tweetfactor.co.uk/current/redis.conf"<br />
    w.stop = "kill `cat /var/run/redis.pid`"<br />
    w.restart = "kill `cat /var/run/redis.pid`; redis-server /var/www/tweetfactor.co.uk/current/redis.conf"<br />
    w.start_grace = 10.seconds<br />
    w.restart_grace = 10.seconds<br />
    w.pid_file = "/var/run/redis.pid"</p>
<p>    w.behavior(:clean_pid_file)</p>
<p>    w.start_if do |start|<br />
        start.condition(:process_running) do |c|<br />
            c.interval = 5.seconds<br />
            c.running = false<br />
        end<br />
    end</p>
<p>    w.restart_if do |restart|<br />
        restart.condition(:memory_usage) do |c|<br />
            c.above = 30.megabytes<br />
            c.times = [3, 5] # 3 out of 5 intervals<br />
        end</p>
<p>        restart.condition(:cpu_usage) do |c|<br />
            c.above = 30.percent<br />
            c.times = 5<br />
        end<br />
    end</p>
<p>    # lifecycle<br />
    w.lifecycle do |on|<br />
        on.condition(:flapping) do |c|<br />
            c.to_state = [:start, :restart]<br />
            c.times = 5<br />
            c.within = 5.minute<br />
            c.transition = :unmonitored<br />
            c.retry_in = 10.minutes<br />
            c.retry_times = 5<br />
            c.retry_within = 2.hours<br />
        end<br />
    end<br />
end</p>
<p>God.watch do |w|<br />
    w.name = "twitter_filter"<br />
    w.interval = 30.seconds<br />
    w.start = "cd /var/www/tweetfactor.co.uk/current/; ruby twitter_filter.rb start"<br />
    w.stop =  "cd /var/www/tweetfactor.co.uk/current/; ruby twitter_filter.rb stop"<br />
    w.start_grace = 10.seconds<br />
    w.restart_grace = 10.seconds<br />
    w.pid_file = "/var/www/tweetfactor/releases/log/twitter_filter.pid"</p>
<p>    w.behavior(:clean_pid_file)</p>
<p>    w.start_if do |start|<br />
        start.condition(:process_running) do |c|<br />
            c.interval = 5.seconds<br />
            c.running = false<br />
        end<br />
    end</p>
<p>    w.restart_if do |restart|<br />
        restart.condition(:memory_usage) do |c|<br />
            c.above = 30.megabytes<br />
            c.times = [3, 5] # 3 out of 5 intervals<br />
        end</p>
<p>        restart.condition(:cpu_usage) do |c|<br />
            c.above = 30.percent<br />
            c.times = 5<br />
        end<br />
    end</p>
<p>    # lifecycle<br />
    w.lifecycle do |on|<br />
        on.condition(:flapping) do |c|<br />
            c.to_state = [:start, :restart]<br />
            c.times = 5<br />
            c.within = 5.minute<br />
            c.transition = :unmonitored<br />
            c.retry_in = 10.minutes<br />
            c.retry_times = 5<br />
            c.retry_within = 2.hours<br />
        end<br />
    end<br />
end<br />
</code>
</li>
<li>A quick <code>chmod +x god /etc/init.d/god</code></li>
<li>And a <code>sudo update-rc.d god defaults</code> to have it added to startup.</li>
<li>I need to add a rackup config file in the root called config.ru so that Nginx/Passenger could handle the Sinatra app:<br />
<code><br />
require 'rubygems'<br />
require 'sinatra'</p>
<p>require 'tweetfactor'</p>
<p>set :environment, :production</p>
<p>run Sinatra::Application<br />
</code>
</li>
<li>The last thing I had to do was modify my twitter_filter.rb from the original blog post so it could be daemonized, I messaged digitalhobbit for some help on this and he sent me a <a href="http://gist.github.com/251724">modified version</a> which worked a charm.  I also had to <code>sudo gem install daemons</code></li>
</ol>
<p>I had a fun few hours learning about a <em>tonne</em> of new stuff and I hope this may help you if you wanna deploy it too.</p>
<p>Any questions, shoot in the comments!</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/kill-a-process-using-its-pid-file' rel='bookmark' title='Permanent Link: Kill A Process Using It&#8217;s PID File'>Kill A Process Using It&#8217;s PID File</a></li><li><a href='http://www.adamjctaylor.com/open-melody-homebrew-and-catalyst-mojo' rel='bookmark' title='Permanent Link: Open Melody, Homebrew, Catalyst/Mojo and Sinatra.'>Open Melody, Homebrew, Catalyst/Mojo and Sinatra.</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/tweetfactor-an-experiment-using-ruby-sinatra-twitter-and-redis/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Kill A Process Using It&#8217;s PID File</title>
		<link>http://www.adamjctaylor.com/kill-a-process-using-its-pid-file</link>
		<comments>http://www.adamjctaylor.com/kill-a-process-using-its-pid-file#comments</comments>
		<pubDate>Mon, 07 Dec 2009 20:46:21 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=465</guid>
		<description><![CDATA[Quick Tip: kill $(cat /var/run/redis.pid) I needed to do that earlier and didn&#8217;t know how. EDIT: Turns out you can just do this as well: kill `cat /var/run/redis.pid` Related posts:Finding which package a file belongs to on DebianRunning a unix command as a background processTweetfactor &#8211; An experiment using Ruby, Sinatra, Twitter and Redis]]></description>
			<content:encoded><![CDATA[<p></p><p>Quick Tip: kill $(cat /var/run/redis.pid)</p>
<p>I needed to do that earlier and didn&#8217;t know how.</p>
<p>EDIT: Turns out you can just do this as well: kill `cat /var/run/redis.pid`</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/finding-which-package-a-file-belongs-to-on-debian' rel='bookmark' title='Permanent Link: Finding which package a file belongs to on Debian'>Finding which package a file belongs to on Debian</a></li><li><a href='http://www.adamjctaylor.com/running-a-unix-command-as-a-background-process' rel='bookmark' title='Permanent Link: Running a unix command as a background process'>Running a unix command as a background process</a></li><li><a href='http://www.adamjctaylor.com/tweetfactor-an-experiment-using-ruby-sinatra-twitter-and-redis' rel='bookmark' title='Permanent Link: Tweetfactor &#8211; An experiment using Ruby, Sinatra, Twitter and Redis'>Tweetfactor &#8211; An experiment using Ruby, Sinatra, Twitter and Redis</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/kill-a-process-using-its-pid-file/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using TheSchwartz (Job Queue) with Catalyst</title>
		<link>http://www.adamjctaylor.com/using-theschwartz-job-queue-with-catalyst</link>
		<comments>http://www.adamjctaylor.com/using-theschwartz-job-queue-with-catalyst#comments</comments>
		<pubDate>Mon, 02 Nov 2009 21:07:12 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[catalyst]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=374</guid>
		<description><![CDATA[TheSchwartz is a job queue module written by the guy(s) behind LiveJournal. It simply allows you to add jobs to a queue, in this case a database, and then have scripts watching the queue (database) and running work tasks when jobs arrive that they know how to deal with. I wrote down how I used [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><a href="http://search.cpan.org/~bradfitz/TheSchwartz-1.07/lib/TheSchwartz.pm">TheSchwartz</a> is a job queue module written by the guy(s) behind LiveJournal.  It simply allows you to add jobs to a queue, in this case a database, and then have scripts watching the queue (database) and running work tasks when jobs arrive that they know how to deal with.</p>
<p>I wrote down how I used it with Catalyst because there&#8217;s not a whole lot of documentation about how to use it available.<br />
<span id="more-374"></span><br />
1. force install TheSchwartz &#8211; the module fails tests and according to a message on a thread it&#8217;s fine to force install, I haven&#8217;t had any problems.</p>
<p>2. You have to create the required database tables, which is mentioned in  <a href="http://cpansearch.perl.org/src/BRADFITZ/TheSchwartz-1.07/doc/schema.sql">some hidden documentation</a>.</p>
<p>3. Then what I did was to create a wrapper class for TheSchwartz so that I could invoke it from inside Catalyst and from my worker scripts outside of Cataylst.  Mine looked like this, it may well be you know a better way of writing it:</p>
<pre>
package Norris::TheSchwartzWrapper;

use strict;
use warnings;
use base qw /TheSchwartz/;

sub new {
    my $class = shift;

    ## todo make the non database options OPTIONS
    return $class->SUPER::new(
        databases => [ {
            dsn => 'dbi:mysql:norris_jobs',
            user => 'root',
            pass => ''
        } ],
        verbose => 1,
        driver_cache_expiration => 300,
    );
}

1;
</pre>
<p>If you copy that you might wanna actually do the refactor allowing the passing of options.  </p>
<p>3. Following a <a href="http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg05108.html<br />
">discussion on a mailing list</a> I created a model wrapper [for the wrapper] for TheSchwartz.  The post talks about wrapping TheScwhartz object directly but because we&#8217;ve already decoupled TheSchwartz from out Catalyst application we wrap the wrapper&#8230;</p>
<p>Basically, &#8220;use&#8221; your wrapper and then create a model with the following: </p>
<pre>
sub COMPONENT {
    return Norris::TheSchwartzWrapper->new();
}
</pre>
<p>That allows you to do $c->model(&#8216;Model&#8217;)->insert() and access TheSchwartz API.</p>
<p>4. At this point it didn&#8217;t work for me &#8211; MAKE SURE YOU HAVE SOME DB DRIVERS INSTALLED &#8211; I did not and hence inserting jobs was failing.</p>
<p>5. <a href="http://search.cpan.org/~bradfitz/TheSchwartz-1.07/lib/TheSchwartz/Job.pm">Insert jobs</a> from a controller or wherever:</p>
<pre>$c->model('TheSchwartz')->insert( 'Norris::Scanner::Crawler', $job_args ); </pre>
<p>6. Create <a href="http://search.cpan.org/~bradfitz/TheSchwartz-1.07/lib/TheSchwartz/Worker.pm">worker scripts</a>.</p>
<p>7. Sit back and relax!</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/open-melody-homebrew-and-catalyst-mojo' rel='bookmark' title='Permanent Link: Open Melody, Homebrew, Catalyst/Mojo and Sinatra.'>Open Melody, Homebrew, Catalyst/Mojo and Sinatra.</a></li><li><a href='http://www.adamjctaylor.com/mad-lib-perl-snippet' rel='bookmark' title='Permanent Link: Mad-Lib Perl Snippet'>Mad-Lib Perl Snippet</a></li><li><a href='http://www.adamjctaylor.com/become-a-perl-rockstar' rel='bookmark' title='Permanent Link: Become a Perl rockstar&#8230; AKA Perl link dump'>Become a Perl rockstar&#8230; AKA Perl link dump</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/using-theschwartz-job-queue-with-catalyst/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Melody, Homebrew, Catalyst/Mojo and Sinatra.</title>
		<link>http://www.adamjctaylor.com/open-melody-homebrew-and-catalyst-mojo</link>
		<comments>http://www.adamjctaylor.com/open-melody-homebrew-and-catalyst-mojo#comments</comments>
		<pubDate>Fri, 25 Sep 2009 07:33:40 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=362</guid>
		<description><![CDATA[I just wanted to quickly highlight some interesting projects I&#8217;ve come across lately&#8230; Open Melody Open Melody is a fork of the popular blogging [/social media] platform Moveable Type. Its aim is to be completely backward compatible with Moveable Type but to have a more democratic development style. One of the benefits of the Moveable [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I just wanted to quickly highlight some interesting projects I&#8217;ve come across lately&#8230;</p>
<h3>Open Melody</h3>
<p><img src="http://openmelody.org/images/badge-iheartmelody-black.png" alt="open melody" /></p>
<p><a href="http://openmelody.org/">Open Melody</a> is a fork of the popular blogging [/social media] platform Moveable Type.  Its aim is to be completely backward compatible with Moveable Type but to have a more democratic development style.</p>
<p><span id="more-362"></span></p>
<p>One of the benefits of the Moveable Type system is that all posts are &#8220;published&#8221; rather than dynamically generated, i.e. from the posts a whole set of static html pages are created which can be served rather than database intense dynamic pages.</p>
<p>They want to encourage as much community participation as possible and all the <a href="http://github.com/openmelody/melody">code is on github</a> for anyone to jump right in.</p>
<p>If nothing else they have a lovely looking website and I wish them all the best and look forward to seeing what becomes of this.</p>
<h3>Homebrew</h3>
<p>I love my MacBook Pro and OS X, I really do but there are times I miss being able to issue &#8220;sudo aptitude install apache&#8221; or whatever.  Admittedly <a href="http://www.finkproject.org/">Fink</a> [currently down] has worked well for me but I definitely plan to try out <a href="http://github.com/mxcl/homebrew/tree">Homebrew, which is a new package manager for OS X</a>. It was written by a <a href="http://twitter.com/mxcl">guy I started <strike>stalking</strike>following on twitter</a> because he works at last.fm! </p>
<h3>Catalyst and Mojo</h3>
<p><a href="http://mojolicious.org/">Mojo</a> is a modern web framework written in Perl with an aim of being easy to install and having limited/no(?) dependencies.  I actually applied to Google Summer of Code with Mojo but that&#8217;s another story&#8230;</p>
<p>Over the last week or two I&#8217;ve been working with Mojo&#8217;s big brother <a href="http://www.catalystframework.org/">Catalyst</a>.  Catalyst is the opposite of Mojo in the &#8220;easy to install/lack of dependencies&#8221; but <a href="irc://irc.perl.org/catalyst">the guys in IRC</a> are very helpful and the power and flexibility of Catalyst is awesome!  It&#8217;s not as quick as bashing up a site in Rails admittedly but I am looking forward to using it more and also <a href="<a href="http://www.amazon.co.uk/gp/product/1430223650?ie=UTF8&#038;tag=whishapo-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=1430223650">the book</a> [aff link] is meant to be great!</p>
<h3>Sinatra</h3>
<p><a href="http://www.sinatrarb.com/">Sinatra</a> is a very simple and lightweight web framework written in Ruby.  I&#8217;ve used it because it seems better than static HTML because you can set up simple URL routing:</p>
<p><code><br />
get '/' do<br />
  erb :index<br />
end<br />
</code></p>
<p><code><br />
get '/about' do<br />
  erb :about<br />
end<br />
</code></p>
<p>and you can have partial templates for footers etc.  So basically better than PHP for a simple site.</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/using-theschwartz-job-queue-with-catalyst' rel='bookmark' title='Permanent Link: Using TheSchwartz (Job Queue) with Catalyst'>Using TheSchwartz (Job Queue) with Catalyst</a></li><li><a href='http://www.adamjctaylor.com/become-a-perl-rockstar' rel='bookmark' title='Permanent Link: Become a Perl rockstar&#8230; AKA Perl link dump'>Become a Perl rockstar&#8230; AKA Perl link dump</a></li><li><a href='http://www.adamjctaylor.com/tweetfactor-an-experiment-using-ruby-sinatra-twitter-and-redis' rel='bookmark' title='Permanent Link: Tweetfactor &#8211; An experiment using Ruby, Sinatra, Twitter and Redis'>Tweetfactor &#8211; An experiment using Ruby, Sinatra, Twitter and Redis</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/open-melody-homebrew-and-catalyst-mojo/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free iPhone development screencast</title>
		<link>http://www.adamjctaylor.com/free-iphone-development-screencast</link>
		<comments>http://www.adamjctaylor.com/free-iphone-development-screencast#comments</comments>
		<pubDate>Tue, 25 Aug 2009 21:22:28 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=337</guid>
		<description><![CDATA[To celebrate the launch of Mobile Orchard Screencasts they are giving away the first one free for a week. It is a seven minute long screencast about running code on the iPhone. Get it while it&#8217;s hot, in a weeks time it&#8217;ll cost you $5. Related posts:Free laptop wtf?In the news &#8211; 02/07/07]]></description>
			<content:encoded><![CDATA[<p></p><p>To celebrate the launch of <a href="http://www.mobileorchard.com/category/screencasts/">Mobile Orchard Screencasts</a> they are giving away the first one free for a week.</p>
<p>It is a seven minute long screencast about <a href="http://www.mobileorchard.com/iphone-development-provisioning/">running code on the iPhone</a>.</p>
<p>Get it while it&#8217;s hot, in a weeks time it&#8217;ll cost you $5.</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/free-laptop-wtf' rel='bookmark' title='Permanent Link: Free laptop wtf?'>Free laptop wtf?</a></li><li><a href='http://www.adamjctaylor.com/in-the-news-020707' rel='bookmark' title='Permanent Link: In the news &#8211; 02/07/07'>In the news &#8211; 02/07/07</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/free-iphone-development-screencast/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>LWP::UserAgent and SSL</title>
		<link>http://www.adamjctaylor.com/lwpuseragent-and-ssl</link>
		<comments>http://www.adamjctaylor.com/lwpuseragent-and-ssl#comments</comments>
		<pubDate>Fri, 21 Aug 2009 11:57:45 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=334</guid>
		<description><![CDATA[I&#8217;ve just spent the best part of a day, banging my head, trying to figure out why I couldn&#8217;t get LWP::UserAgent to connect to a URL (which happened to be an https url). I was looking at headers, manually in the browser, tried sending the request through a proxy, and finally, earlier today I used [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I&#8217;ve just spent the best part of a day, banging my head, trying to figure out why I couldn&#8217;t get LWP::UserAgent to connect to a URL (which happened to be an https url).  I was looking at headers, manually in the browser, tried sending the request through a proxy, and finally, earlier today I used <a href="http://www.latenightsw.com/affrus/index.html">Affrus</a> to step through the code visually and inspect LWP::UserAgent, Net::OAuth and my module (WWW::Yammer).  </p>
<p>I found a small mention about <a href="http://search.cpan.org/perldoc?Crypt::SSLeay">Crypt::SSLeay</a> and thought, no way, I bashed my head for a day and a half over a missing module that there was no obvious [to me] mention of?! </p>
<p>Well, I installed it, and hey-presto, it now works.</p>
<p>So if your banging your head trying to use LWP::UserAgent to connect to an https URL, ensure you have <a href="http://search.cpan.org/perldoc?Crypt::SSLeay">Crypt::SSLeay</a> installed.</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/textmate-and-git' rel='bookmark' title='Permanent Link: Textmate and Git'>Textmate and Git</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/lwpuseragent-and-ssl/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Become a Perl rockstar&#8230; AKA Perl link dump</title>
		<link>http://www.adamjctaylor.com/become-a-perl-rockstar</link>
		<comments>http://www.adamjctaylor.com/become-a-perl-rockstar#comments</comments>
		<pubDate>Thu, 20 Aug 2009 19:31:44 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=315</guid>
		<description><![CDATA[Photo: I&#8217;m not a rockstar I&#8217;m a poseur. I&#8217;m coding quite a lot of Perl again at the moment and I&#8217;ve been saving quite a lot of interesting Perl links to my delicious account which I&#8217;m going to share with you. They probably won&#8217;t make you a rockstar but it might improve your Perl knowledge. [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><img class="size-full wp-image-317" title="perl-rockstar" src="http://www.adamjctaylor.com/wp-content/uploads/2009/08/perl-rockstar1.jpg" alt="Perl Rockstar" width="500" height="500" /></p>
<p>Photo: <a href="http://www.flickr.com/photos/snapies/3777251726/">I&#8217;m not a rockstar I&#8217;m a poseur</a>.</p>
<p>I&#8217;m coding quite a lot of Perl again at the moment and I&#8217;ve been saving quite a lot of interesting Perl links to <a href="http://delicious.com/adam_">my delicious account</a> which I&#8217;m going to share with you.  They probably won&#8217;t make you a rockstar but it might improve your Perl knowledge. </p>
<p><span id="more-315"></span></p>
<h3>Modules</h3>
<p><a href="http://search.cpan.org/perldoc?Moose">Moose</a> is a collection of Perl modules that add a new, more modern object framework to Perl 5.x.  <del datetime="2009-08-27T15:21:47+00:00"><a href="http://en.wikibooks.org/wiki/Programming_with_Moose">Programming with Moose</a> is a wikibook that discuses the uses and use of Moose.</del>  Actually, apparently the <a href="http://search.cpan.org/~drolsky/Moose-0.89/lib/Moose/Manual.pod">official documentation on CPAN</a> is a better resource for using Moose.</p>
<p><a href="http://mojolicious.org/">Mojo</a> is a new Perl web framework based off the Catalyst framework.  It is designed to have no/limited dependencies so that a Perl newbie can install and get going fairly quickly.  It is still early days but it will be interesting to see how this develops.  </p>
<p>N.B. I just heard some skeptical views about Mojo, especially with a recent release which will have broken many peoples Mojo apps as it was there were major changes in the code base but I do hope that it stabilises and do think it is worth keeping track of. </p>
<h3>Higher Order Perl</h3>
<p><a href="http://blog.plover.com/">HIgher Order Perl</a> is a blog about Perl, computing, maths etc.  I haven&#8217;t read it too much yet but I was planning to trawl through the archives at somepoint because I have a feeling it could be quite interesting (in a nerdy way).</p>
<h3>Profiling</h3>
<p>Profiling, not something I&#8217;ve had to do yet but it is the process of analysing your code to see which routines/loops/blocks could benefit from optimisation rather than blindly optimising what you <em>think</em> may be running slowly.  Here is a <a href="http://www.perl.com/pub/a/2004/06/25/profiling.html">general introduction into profiling perl</a> and here is a <a href="http://open.blogs.nytimes.com/2008/03/05/the-new-york-times-perl-profiler/">perl module released by the NYT</a> for profiling Perl code.  I plan to give that a look should I need to do any profiling.</p>
<h3>Prototypes</h3>
<p>I&#8217;m not talking about little wooden miniatures, prototypes in Perl are like, what&#8217;s the word, parameter declarations in function declarations in other languages?  Except actually, I think they&#8217;re not.  Well anyway, I read a <a href="http://perlhacks.com/2009/06/what-is-wrong-with-this-picture.php">post about Perl prototypes</a>, which was pretty confusing, so then I asked <a href="http://twitter.com/bmxkris">my buddy Kristian</a> to explain.  I also read <a href="http://www.perl.com/language/misc/fmproto.html">another long article about prototypes</a>.  Needless to say I still don&#8217;t fully understand the implications but basically don&#8217;t declare your parameters, I think..?</p>
<h3>Object Orientated Perl</h3>
<p>Even though I wanted to use Moose (see above) I still needed an overview of object orientation in Perl, as I knew from previous experience it was a bit wierd &#8211; bless / self etc&#8230; There was a pretty nice <a href="http://broadcast.oreilly.com/2008/11/beginners-introduction-to-obje.html">article by Chromatic, including some stuff about using Moose</a> and another article about <a href="http://www.codeproject.com/KB/perl/camel_poop.aspx">blessing your father</a>.</p>
<h3>Module Creation</h3>
<p>I&#8217;m currently writing a module that I&#8217;m hopefully going to release to CPAN when finished but I&#8217;d never done that before so I read <a href="http://www.perlmonks.org/?node_id=431702">José&#8217;s guide to creating Perl modules</a> and a <a href="http://www.perlmonks.org/?node_id=158999">guide on Perlmonks</a>.  Also I looked into <a href="http://search.cpan.org/~dconway/Module-Starter-PBP-v0.0.3/lib/Module/Starter/PBP.pm">Module::Builder::PBP on CPAN</a>.</p>
<h3>Misc. Perl Links</h3>
<p><a href="http://www.perl.com/pub/a/2002/11/14/exception.html">Exception handling in Perl</a>.<br />
<a href="http://www.netalive.org/tinkering/serious-perl/">Writing serious Perl: The absolute minimum you need to know.</a><br />
<a href="http://perl.plover.com/FAQs/Namespaces.html">Namespaces &#038; Scoping</a><br />
<a href="http://www.forum.hell.org.ua/Docs/oreilly/perl3/lwp/ch12_03.htm">A link checking spider</a> (I do not condone copyright infringement but that is a useful link for me as I&#8217;ll be writing a Perl spider soon..)<br />
<a href="http://docs.google.com/gview?a=v&#038;q=cache:nBQbmqID7NcJ:www.wgz.org/chromatic/perl/IntroTestMore.pdf+perl+test+more&#038;hl=en&#038;gl=uk">Intro to Test::More</a> (Googledoc/PDF)</p>
<p>That&#8217;s your lot for today, if there are other great Perl articles or blogs I&#8217;d love to know about them..</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/perl-aint-dead' rel='bookmark' title='Permanent Link: Perl Ain&#8217;t Dead&#8230;'>Perl Ain&#8217;t Dead&#8230;</a></li><li><a href='http://www.adamjctaylor.com/mad-lib-perl-snippet' rel='bookmark' title='Permanent Link: Mad-Lib Perl Snippet'>Mad-Lib Perl Snippet</a></li><li><a href='http://www.adamjctaylor.com/using-theschwartz-job-queue-with-catalyst' rel='bookmark' title='Permanent Link: Using TheSchwartz (Job Queue) with Catalyst'>Using TheSchwartz (Job Queue) with Catalyst</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/become-a-perl-rockstar/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Textmate and Git</title>
		<link>http://www.adamjctaylor.com/textmate-and-git</link>
		<comments>http://www.adamjctaylor.com/textmate-and-git#comments</comments>
		<pubDate>Thu, 20 Aug 2009 10:00:09 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[scm]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://www.adamjctaylor.com/?p=326</guid>
		<description><![CDATA[If you&#8217;ve installed git and use textmate you may receive errors about git not being installed correctly until you do the following: run &#8220;which git&#8221; on the command line and note the output. in textmate write &#8220;echo $PATH&#8221; and check to see that the path returned from which git is present &#8211; in my case [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>If you&#8217;ve installed git and use textmate you may receive errors about git not being installed correctly until you do the following:</p>
<ol>
<li>run &#8220;which git&#8221; on the command line and note the output.</li>
<li>in textmate write &#8220;echo $PATH&#8221; and check to see that the path returned from which git is present &#8211; in my case it was</li>
<li>Open textmate preferences -> advanced -> shell variables and add a new shell variable: TM_GIT with the value of what was returned from &#8220;which git&#8221; e.g. /usr/local/git/bin/git</li>
</ol>
<p>Now it should work.</p>


<p>Related posts:<ol><li><a href='http://www.adamjctaylor.com/textmate-micro-blog' rel='bookmark' title='Permanent Link: TextMate Micro-Blog'>TextMate Micro-Blog</a></li><li><a href='http://www.adamjctaylor.com/stacks-heaps-variables-and-pointers' rel='bookmark' title='Permanent Link: Stacks, Heaps, Variables and Pointers'>Stacks, Heaps, Variables and Pointers</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.adamjctaylor.com/textmate-and-git/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
