#  You may distribute under the terms of either the GNU General Public License
#  or the Artistic License (the same terms as Perl itself)
#
#  (C) Paul Evans, 2010 -- leonerd@leonerd.org.uk

package Plack::Handler::FCGI::Async;

use strict;
use warnings;

use FCGI::Async::PSGI;
use IO::Async::Loop;

our $VERSION = '0.21';

=head1 NAME

C<Plack::Handler::FCGI::Async> - FastCGI handler for Plack using L<FCGI::Async>

=head1 DESCRIPTION

This module allows L<Plack> to run a L<PSGI> application as a standalone
FastCGI daemon under L<IO::Async>, by using L<FCGI::Async>.

 plackup -s FCGI::Async --listen ":2000" application.psgi

This is internally implemented using L<FCGI::Async::PSGI>; further information
on environment etc.. is documented there.

=cut

sub new
{
   my $class = shift;
   my %opts = @_;

   delete $opts{host};
   delete $opts{port};

   my $self = bless {
      map { $_ => delete $opts{$_} } qw( listen server_ready socket ),
   }, $class;

   keys %opts and die "Unrecognised keys " . join( ", ", sort keys %opts );

   return $self;
}

sub run
{
   my $self = shift;
   my ( $app ) = @_;

   my $loop = IO::Async::Loop->new;

   foreach my $listen ( @{ $self->{listen} } ) {
      my $fcgi = FCGI::Async::PSGI->new(
         app => $app,
      );

      $loop->add( $fcgi );

      my %listenargs;
      if( $self->{socket} ) {
         $listenargs{handle} = $self->{socket};
      }
      else {
         ( $listenargs{host}, $listenargs{service} ) = $listen =~ m/^(.*):(.*?)$/;
      }

      $fcgi->listen(
         %listenargs,
         on_notifier => sub { $self->{server_ready} and $self->{server_ready}->() },

         on_resolve_error => sub {
            die "Cannot resolve - $_[-1]\n";
         },
         on_listen_error => sub {
            die "Cannot listen - $_[-1]\n";
         },
      );
   }

   $loop->loop_forever;
}

# Keep perl happy; keep Britain tidy
1;

__END__

=head1 SEE ALSO

=over 4

=item *

L<FCGI::Async> - use FastCGI with L<IO::Async>

=item *

L<Plack> - Perl Superglue for Web frameworks and Web Servers (PSGI toolkit)

=back

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>
