Skip to content
This repository

Plack-based nonblocking Web framework for IO-bound delayed response, server push (streaming) and long-poll comet

branch: xmpp

This branch is 0 commits ahead and 82 commits behind master

Fetching latest commit…


Cannot retrieve the latest commit at this time

Octocat-spinner-32 eg
Octocat-spinner-32 inc
Octocat-spinner-32 lib
Octocat-spinner-32 t
Octocat-spinner-32 xt initial commit October 14, 2009
Octocat-spinner-32 .gitignore
Octocat-spinner-32 .shipit initial commit October 14, 2009
Octocat-spinner-32 Changes
Octocat-spinner-32 MANIFEST
Octocat-spinner-32 MANIFEST.SKIP
Octocat-spinner-32 Makefile.PL
Octocat-spinner-32 README
    Tatsumaki - Non-blocking Web server and framework based on AnyEvent

      use Tatsumaki::Error;
      use Tatsumaki::Application;
      use Tatsumaki::HTTPClient;
      use Tatsumaki::Server;

      package MainHandler;
      use base qw(Tatsumaki::Handler);

      sub get {
          my $self = shift;
          $self->write("Hello World");

      package FeedHandler;
      use base qw(Tatsumaki::Handler);

      use JSON;

      sub get {
          my($self, $query) = @_;
          my $client = Tatsumaki::HTTPClient->new;
          $client->get("$query", sub { $self->on_response(@_) });

      sub on_response {
          my($self, $res) = @_;
          if ($res->is_error) {
          my $json = JSON::decode_json($res->content);
          $self->write("Fetched " . scalar(@{$json->{entries}}) . " entries from API");

      package StreamWriter;
      use base qw(Tatsumaki::Handler);

      use AnyEvent;

      sub get {
          my $self = shift;

          my $try = 0;
          my $t; $t = AE::timer 0, 0.1, sub {
              $self->stream_write("Current UNIX time is " . time . "\n");
              if ($try++ >= 10) {
                  undef $t;

      package main;

      my $app = Tatsumaki::Application->new([
          '/stream' => 'StreamWriter',
          '/feed/(\w+)' => 'FeedHandler',
          '/' => 'MainHandler',

      if (__FILE__ eq $0) {
          Tatsumaki::Server->new(port => 9999)->run($app);
      } else {
          return $app->psgi_app;

    This is my personal, toy and experimental project. The API will be
    added, updated or removed without any notice until it gets CPAN. As long
    as you're playing with git, keep that in mind, and don't blame me if one
    day your application stops running :)

    Tatsumaki is a toy port of Tornado for Perl using Plack (with
    non-blocking extensions) and AnyEvent.

    It allows you to write a web application that does a immediate response
    with template rendering, IO-bound delayed response (like fetching third
    party API or XML feeds), server push streaming and long-poll Comet in a
    clean unified API.

    When "asynchronous" is declared in your application, you need a PSGI
    server backend that supports "psgi.streaming" response style. If your
    application does server push with "stream_write", you need a server that
    supports "psgi.nonblocking" (and "psgi.streaming") as well.

    Currently Tatsumaki asynchronous application is supposed to run on
    Tatsumaki::Server, Plack::Server::AnyEvent, Plack::Server::Coro and

    If "asynchronous" is not used, your application is supposed to run in
    any PSGI standard environments, including blocking multiprocess
    environments like mod_perl2 and prefork.

    Tatsumaki is a Japanese for Tornado. Also, it might sound familiar from
    "Tatsumaki Senpuukyaku" of Ryu from Street Fighter II if you loved the
    Capcom videogame back in the day :)

    Tatsuhiko Miyagawa <>

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    AnyEvent Plack PSGI <>
Something went wrong with that request. Please try again.