From 0afbfaee75e8480e8e0ed0a3bbd3749a4756f727 Mon Sep 17 00:00:00 2001
From: franck cuny <franck@lumberjaph.net>
Date: Fri, 10 Sep 2010 23:25:10 +0200
Subject: initial import

---
 ...te-a-nice-webapp-in-less-than-two-hours.textile | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 _posts/2009-12-21-tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours.textile

(limited to '_posts/2009-12-21-tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours.textile')

diff --git a/_posts/2009-12-21-tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours.textile b/_posts/2009-12-21-tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours.textile
new file mode 100644
index 0000000..bd042e4
--- /dev/null
+++ b/_posts/2009-12-21-tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours.textile
@@ -0,0 +1,102 @@
+---
+layout: post
+category: perl
+title: Tatsumaki, or how to write a nice webapp in less than two hours
+---
+
+Until today, I had a script named "lifestream.pl". This script was triggered via cron once every hour, to fetch various feeds from services I use (like <a href="http://github.com/">github</a>, <a href="http://identi.ca/">identi.ca</a>, ...) and to process the result through a template and dump the result in a HTML file.
+
+Today I was reading <a href="http://github.com/miyagawa/Tatsumaki">Tatsumaki's code</a> and some examples (<a href="http://github.com/gugod/Social">Social</a> and <a href="http://github.com/miyagawa/Subfeedr">Subfeedr</a>). Tatsumaki is a "port" <a href="http://www.tornadoweb.org/">tornado</a> (a non blocking server in Python), based on Plack and AnyEvent. I though that using this to replace my old lifestream script would be a good way to test it. Two hours later I have a complete webapp that works (and the code is available <a href="http://github.com/franckcuny/lifestream">here</a>).
+
+The code is really simple: first, I define an handler for my HTTP request. As I have only one things to do (display entries), the handler is really simple:
+
+{% highlight perl %}
+package Lifestream::Handler;
+use Moose;
+extends 'Tatsumaki::Handler';
+
+sub get {
+    my $self   = shift;
+    my %params = %{$self->request->params};
+    $self->render(
+        'lifestream.html',
+        {   memes    => $self->application->memes($params{page}),
+            services => $self->application->services
+        }
+    );
+}
+1;
+{% endhighlight %}
+
+For all the get request, 2 methods are called : <strong>memes</strong> and <strong>services</strong>. The <strong>memes</strong> get a list of memes to display on the page. The services get the list of the various services I use (to display them on a sidebar).
+
+Now, as I don't want to have anymore my lifestream.pl script in cron, I will let Tatsumaki do the polling. For this, I add a service to my app, which is just a worker.
+
+{% highlight perl %}
+package Lifestream::Worker;
+use Moose;
+extends 'Tatsumaki::Service';
+use Tatsumaki::HTTPClient;
+
+sub start {
+    my $self = shift;
+    my $t;
+    $t = AE::timer 0, 1800, sub {
+        scalar $t;
+        $self->fetch_feeds;
+    };
+}
+
+sub fetch_feeds {
+    my ($self, $url) = @_;
+    Tatsumaki::HTTPClient->new->get(
+        $url,
+        sub {
+            #do the fetch and parsing stuff
+        }
+    );
+}
+{% endhighlight %}
+
+From now, every 60 minutes, feeds will be checked. Tatsumaki::HTTPClient is a HTTP client based on AnyEvent::HTTP.
+
+Let's write the app now
+
+{% highlight perl %}
+package Lifestream;
+
+use Moose;
+extends "Tatsumaki::Application";
+
+use Lifestream::Handler;
+use Lifestream::Worker;
+
+sub app {
+    my ($class, %args) = @_;
+    my $self = $class->new(['/' => 'Lifestream::Handler',]);
+    $self->config($args{config});
+    $self->add_service(Lifestream::Worker->new(config => $self->config));
+    $self;
+}
+
+sub memes {
+}
+
+sub services {
+}
+{% endhighlight %}
+
+The <strong>memes</strong> and <strong>services</strong> method called from the handler are defined here. In the app method, I "attch" the "/" path to the handler, and I add the service.
+
+and to launch the app
+
+{% highlight perl %}
+my $app = Lifestream->app(config => LoadFile($config));
+require Tatsumaki::Server;
+Tatsumaki::Server->new(
+    port => 9999,
+    host => 0,
+)->run($app);
+{% endhighlight %}
+
+And that's it, I now have a nice webapp, with something like only 200 LOC. I will keep playing with <a href="http://www.slideshare.net/miyagawa/tatsumaki">Tatsumaki</a> as I have more ideas (and probably subfeedr too). Thanks to <a href="http://bulknews.typepad.com/">miyagawa</a> for all this code.
-- 
cgit v1.2.3

