FCGI-EV-Std
view release on metacpan or search on metacpan
lib/FCGI/EV/Std/Nonblock.pm view on Meta::CPAN
package FCGI::EV::Std::Nonblock;
use 5.010001;
use warnings;
use strict;
use utf8;
use Carp;
our $VERSION = 'v2.0.1';
use Scalar::Util qw( weaken refaddr );
use FCGI::EV::Std;
$FCGI::EV::Std::BLOCKING= 0;
$FCGI::EV::Std::MAIN = \&new;
$FCGI::EV::Std::HUP = \&HUP;
my $CB_START = \&main::START;
my $CB_PRE = \&main::PRE;
my $CB_POST = \&main::POST;
my $CB_ERROR = \&main::ERROR;
#my $HUP = undef;
my (%Active, %Server);
sub new {
my ($server) = @_;
my $self = bless {}, __PACKAGE__;
$Active{ refaddr($self) } = $server;
$Server{ refaddr($server) } = $self;
weaken( $Active{ refaddr($self) } );
$self->_wrapper($CB_START);
return;
}
sub done {
my ($self) = @_;
if (exists $Active{ refaddr($self) }) {
my $server = delete $Active{ refaddr($self) };
if ($server) {
delete $Server{ refaddr($server) };
$server->stdout(q{}, 1);
}
}
else {
croak 'this request already done()';
}
return;
}
sub HUP {
my ($server) = @_;
return if !$server; # may happens during global destruction
if (exists $Server{ refaddr($server) }) {
my $self = delete $Server{ refaddr($server) };
# $HUP && $HUP->($self);
}
return;
}
sub send { ## no critic (ProhibitBuiltinHomonyms)
my ($self, $buf) = @_;
my $server = $Active{ refaddr($self) };
if ($server) {
$server->stdout($buf, 0);
}
return;
}
sub wrap_cb {
my ($self, $cb, @p) = @_;
weaken(my $this = $self);
return sub { $this && $this->_wrapper($cb, @p, @_) };
}
sub _wrapper {
my ($this, $cb, @p) = @_;
$CB_PRE->($this);
my $err = eval { $cb->($this, @p); 1 } ? undef : $@;
$CB_POST->($this);
if (defined $err) {
$CB_ERROR->($this, $err);
}
return;
}
1; # Magic true value required at end of module
__END__
=encoding utf8
=for stopwords PRE
=head1 NAME
FCGI::EV::Std::Nonblock - Ease non-blocking CGI using FCGI::EV::Std
=head1 VERSION
This document describes FCGI::EV::Std::Nonblock version v2.0.1
=head1 SYNOPSIS
use FCGI::EV;
use FCGI::EV::Std;
use FCGI::EV::Std::Nonblock; # just loading module will activate it!
FCGI::EV->new($sock, 'FCGI::EV::Std');
#
# Example CGI with FCGI::EV::Std::Nonblock interface
#
sub PRE {}
sub POST {}
sub ERROR {}
sub START {
my ($this) = @_;
$this->{timer} = EV::timer 1, 0, $this->wrap_cb(\&reply);
}
sub reply {
my ($this) = @_;
$this->send("Status: 200 OK\r\n");
$this->send("Content-Type: text/plain\r\n\r\n");
$this->send("Reply after 1 sec!");
$this->done();
( run in 0.636 second using v1.01-cache-2.11-cpan-63c85eba8c4 )