Created
October 5, 2009 13:37
-
-
Save mala/202121 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Plack::Middleware::AsyncSupport; | |
use strict; | |
use warnings; | |
use base qw/Plack::Middleware/; | |
our $USE_CORO = 1; | |
use Coro; | |
use Coro::Channel; | |
use IO::Handle::Util qw(io_from_getline); | |
sub call { | |
my $self = shift; | |
my $env = shift; | |
my $res = $self->app->($env); | |
my $body = $res->[2]; | |
if (ref $body eq "CODE" && $USE_CORO) { | |
my $queue = Coro::Channel->new; | |
async { | |
my $closed = 0; | |
my $cancel = $body->( | |
sub { warn "write"; $queue->put($_[0]) }, # write cb | |
sub { warn "close"; $closed = 1; $queue->shutdown; }, # close cb | |
); | |
if (!$closed) { | |
# TODO: event based code, wait close cb, check timeout | |
} | |
}; | |
$res->[2] = io_from_getline sub { $queue->get }; | |
} elsif (ref $body eq "CODE") { | |
# TODO | |
# $res->[2] = Plack::AsyncResponse->new($env, $body); | |
} | |
return $res; | |
} | |
1; | |
__END__ | |
=head1 NAME | |
Plack::Middleware::AsyncSupport - convert coderef to Stream | |
=head1 SYNOPSIS | |
use Plack::Builder; | |
use Plack::Middleware qw(AsyncSupport); | |
# your app with coro | |
# blocking code, run in thread(Coro) or fork | |
use Coro::Timer qw(sleep); | |
my $app = sub { | |
my $body = sub { | |
my ($writer, $close) = @_; | |
my $i = 0; | |
while ($i < 10) { | |
$writer->(time . "\n"); | |
sleep 1; | |
$i++; | |
} | |
$close->(); | |
}; | |
return [200, [], $body]; | |
}; | |
# TODO: your app with AnyEvent | |
# non-blocking code, return canceler | |
my $app = sub { | |
my $body = sub { | |
my ($writer, $close) = @_; | |
my $i = 0; | |
my $timer; $timer = AE::timer 0, 1, sub { | |
$writer->(time . "\n"); | |
$i++; | |
if ($i >= 10) { | |
$close->(); | |
undef $timer; | |
} | |
}; | |
return sub { undef $timer } # canceler & keep $timer | |
}; | |
return [200, [], $body]; | |
}; | |
builder { | |
enable Plack::Middleware::OtherMiddleware; | |
enable Plack::Middleware::AsyncSupport; | |
$app; | |
}; | |
=head1 DESCRIPTION | |
=head1 AUTHOR | |
mala | |
=head1 SEE ALSO | |
L<Plack::Middleware> L<Plack::Builder> | |
=cut | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment