Coro-Twiggy
view release on metacpan or search on metacpan
lib/Coro/Twiggy.pm view on Meta::CPAN
package Coro::Twiggy;
use 5.008008;
use strict;
use warnings;
use Twiggy::Server;
use Scalar::Util 'weaken';
use Coro;
use Data::Dumper;
our $VERSION = '0.03';
=head1 NAME
Coro::Twiggy - Coro interface for L<Twiggy>
=head1 SYNOPSIS
use Coro::Twiggy;
use Plack::Request;
use Coro::AnyEvent;
my $application = sub {
my ($env) = @_;
my $req = Plack::Request->new($env);
Coro::AnyEvent::sleep 10;
...
return [
200,
[ 'Content-Type' => 'text/html' ],
[ 'Twiggy response after 10 seconds' ]
]
};
my $server = Coro::Twiggy->new(host => '127.0.0.1', port => 8080);
$server->register_service( $application );
=head1 DESCRIPTION
The server starts Your application in L<Coro/async> coroutine and uses its
return value to respond to client.
Application have to return an B<ARRAYREF> with the following items:
=over
=item *
HTTP-code;
=item *
an B<ARRAYREF> that contains headers for response;
=item *
an B<ARRAYREF> that contains body of response.
=back
To stop server destroy server object
=head1 METHODS
=cut
use constant DEFAULT_SERVICE => sub {
[
503,
[ 'Content-Type' => 'text/plain' ],
[ 'There is no registered PSGI service' ]
]
};
=head2 new
Constructor. Returns server.
=head3 Named arguments
=over
=item host
=item port
=item service
PSGI application
=back
=cut
sub new {
my ($class, %opts) = @_;
my $host = $opts{host};
my $port = $opts{port} || 8080;
my $listen = $opts{listen};
lib/Coro/Twiggy.pm view on Meta::CPAN
sub {
my ($env) = @_;
sub {
my ($cb) = @_;
async {
return DEFAULT_SERVICE->() unless $self;
my @res = eval { $self->{app}->($env, $self) };
my $res = shift @res;
if (my $err = $@) {
utf8::encode($err) if utf8::is_utf8 $err;
$cb->([ 500, [ 'Content-Type' => 'text/plain' ], [ $err ]]);
return;
}
my $msg;
unless('ARRAY' eq ref $res) {
$msg = 'PSGI application have to return an ARRAYREF';
goto WRONG_RES;
}
goto WRONG_RES unless @$res >= 2;
push @$res => [] unless @$res > 2;
goto WRONG_RES
unless defined($res->[0]) && $res->[0] =~ /^\d+$/;
goto WRONG_RES unless 'ARRAY' eq ref $res->[1];
goto WRONG_RES unless 'ARRAY' eq ref $res->[2];
$cb->( $res );
return;
WRONG_RES:
$msg ||= "PSGI returned wrong response";
$msg .= "\n\n";
{
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Useqq = 1;
local $Data::Dumper::Deepcopy = 1;
local $Data::Dumper::Maxdepth = 0;
my $dump = Data::Dumper->Dump([ $res, @res ]);
utf8::downgrade($dump) if utf8::is_utf8 $dump;
$msg .= $dump;
}
$cb->( [ 500, [ 'Content-Type', 'text/plain' ], [ $msg ]]);
return;
}
}
}
}
1;
=head1 VCS
L<https://github.com/unera/coro-twiggy>
=head1 AUTHOR
Dmitry E. Oboukhov, <unera@debian.org>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2012 by Dmitry E. Oboukhov
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut
( run in 1.437 second using v1.01-cache-2.11-cpan-b16cb0d3907 )