tokuhirom's Blog

Streaming with PSGI

basic streaming(code by chiba-san https://gist.github.com/2785757)

use strict;
use warnings;

my $app = sub {
    my $env = shift;

      return sub {
          my $responder = shift;
          my $writer = $responder->([ 200, []]);

          for ( 1..5 ) {
              $writer->write("hoge");
              sleep 1;
          }
          $writer->close;
      };
};

$app;

with AnyEvent

use strict;
use warnings;
use utf8;
use 5.010000;
use AnyEvent;
use Time::HiRes qw(sleep);

my $i=0;
sub {
    my $env = shift;
    $env->{'psgi.streaming'} or die "This is not streaming compliant.";

    return sub {
        my $responder = shift;

        my $reqcnt = $i++;
        my $cnt = 0;

        my $writer = $responder->(
            [200, ['Content-Type' => 'text/plain']]
        );
        my $timer; $timer = AE::timer 0, 0.3, sub {
            eval {
                $writer->write("$reqcnt: $cnt\n");
                $cnt++;
            };
            warn $@ if $@;
            if ($cnt > 10) { # stop
                undef $timer;
                $writer->close();
            }
        };
    };
};

with coro

use strict;
use warnings;
use utf8;
use Coro::Timer;

my $i=0;
sub {
    my $env = shift;
    $env->{'psgi.streaming'} or die "This is not streaming compliant.";

    return sub {
        my $responder = shift;

        my $reqcnt = $i++;
        my $cnt = 0;

        my $writer = $responder->(
            [200, ['Content-Type' => 'text/plain']]
        );
        eval {
            for my $cnt (1..10) {
                $writer->write("$reqcnt: $cnt\n");
                Coro::Timer::sleep 0.3 * $cnt;
            }
        };
        warn $@ if $@;
        $writer->close();
    };
};