package FCGI::Engine; use Moose; use CGI::Simple; our $VERSION = '0.19'; our $AUTHORITY = 'cpan:STEVAN'; extends 'FCGI::Engine::Core'; has 'handler_class' => ( metaclass => 'NoGetopt', is => 'ro', isa => 'Str | Object', required => 1, ); has 'handler_method' => ( metaclass => 'NoGetopt', is => 'ro', isa => 'Str', default => sub { 'handler' }, ); has 'handler_args_builder' => ( metaclass => 'NoGetopt', is => 'ro', isa => 'CodeRef', default => sub { sub { CGI::Simple->new } }, ); augment 'initialize' => sub { my ( $self, %addtional_options ) = @_; my $handler_class = $self->handler_class; my $handler_method = $self->handler_method; my $handler_args = $self->handler_args_builder; Class::MOP::load_class($handler_class) unless blessed $handler_class; ($self->handler_class->can($handler_method)) || confess "The handler class (" . $handler_class . ") does not support the handler method (" . $handler_method . ")"; }; sub create_environment { \%ENV } sub handle_request { my $self = shift; my $method = $self->handler_method; $self->handler_class->$method( $self->handler_args_builder->() ); } 1; __END__ =pod =head1 NAME FCGI::Engine - A flexible engine for running FCGI-based applications =head1 SYNOPSIS # in scripts/my_web_app_fcgi.pl use strict; use warnings; use FCGI::Engine; FCGI::Engine->new_with_options( handler_class => 'My::Web::Application', handler_method => 'run', pre_fork_init => sub { require('my_web_app_startup.pl'); } )->run; # run as normal FCGI script perl scripts/my_web_app_fcgi.pl # run as standalone FCGI server perl scripts/my_web_app_fcgi.pl --nproc 10 --pidfile /tmp/my_app.pid \ --listen /tmp/my_app.socket --daemon # see also FCGI::Engine::Manager for managing # multiple FastCGI backends under one script =head1 DESCRIPTION This module helps manage FCGI based web applications by providing a wrapper which handles most of the low-level FCGI details for you. It can run FCGI programs as simple scripts or as full standalone socket based servers who are managed by L. The code is largely based (*cough* stolen *cough*) on the L module, and provides a command line interface which is compatible with that module. But of course it does not require L or anything L related. So you can use this module with your L-based web application or any other L-based web app. =head2 Using with Catalyst, Plack or other web frameworks This module (FCGI::Engine) is B a replacement for L but instead the L (and all it's configuration tools) can be used to manager L apps as well as FCGI::Engine based applications. For example, at work we have an application which has 6 different FCGI backends running. Three of them use an ancient in-house web framework with simple FCGI::Engine wrappers, one which uses L and an FCGI::Engine wrapper and then two L applications. They all happily and peacefully coexist and are all managed with the same L script. As of version 0.11 we now have L/L applications support via the L module. See that module for more information about how it can be used. =head2 Note about CGI.pm usage This module uses L as a sane replacement for CGI.pm, it will pass in a L instance to your chosen C for you, so there is no need to create your own instance of it. There have been a few cases from users who have had bad interactions with CGI.pm and the instance of L we create for you, so before you spend hours looking for bugs in your app, check for this first instead. If you want to change this behavior and not use L then you can override this using the C option, see the docs on that below for more details. =head1 CAVEAT This module is *NIX B, it definitely does not work on Windows and I have no intention of making it do so. Sorry. =head1 PARAMETERS =head2 Command Line This module uses L for command line parameter handling and validation. All parameters are currently optional, but some parameters depend on one another. =over 4 =item I<--listen -l> This should be a file path where the unix domain socket file should live. If this parameter is specified, then you B also specify a location for the pidfile. =item I<--nproc -n> This should be an integer specifying the number of FCGI processes that L should start up. The default is 1. =item I<--pidfile -p> This should be a file path where your pidfile should live. This parameter is only used if the I parameter is specified. =item I<--daemon -d> This is a boolean parameter and has no argument, it is either used or not. It determines if the script should daemonize itself. This parameter only used if the I parameter is specified. =item I<--manager -m> This allows you to pass the name of a L subclass to use. The default is to use L, and any value passed to this parameter B be a subclass of L. =back =head2 Constructor In addition to the command line parameters, there are a couple parameters that the constuctor expects. =over 4 =item I This is expected to be a class name, which will be used inside the request loop to dispatch your web application. =item I This is the class method to be called on the I to server as a dispatch entry point to your web application. It will default to C. =item I This must be a CODE ref that when called produces the arguments to pass to the I. It defaults to a sub which returns a L object. =item I This is an optional CODE reference which will be executed prior to the request loop, and in a multi-proc context, prior to any forking (so as to take advantage of OS COW features). =back =head1 METHODS =head2 Command Line Related =over 4 =item B Returns the value passed on the command line with I<--listen>. This will return a L object. =item B A predicate used to determine if the I<--listen> parameter was specified. =item B Returns the value passed on the command line with I<--nproc>. =item B Returns the value passed on the command line with I<--pidfile>. This will return a L object. =item B A predicate used to determine if the I<--pidfile> parameter was specified. =item B Returns the value passed on the command line with I<--daemon>. =item B A predicate used to determine if the I<--daemon> parameter was specified. =item B Returns the value passed on the command line with I<--manager>. =back =head2 Inspection =over 4 =item B A predicate telling you if anything was passed to the I constructor parameter. =back =head2 Important Stuff =over 4 =item B Call this to start the show. It passes the C<%addtional_options> arguments to both the C sub and as constructor args to the C. =back =head2 Other Stuff =over 4 =item B This is the L BUILD method, it checks some of our parameters to be sure all is sane. =item B This returns the L metaclass assocaited with this class. =back =head1 SEE ALSO =over 4 =item L I took all the guts of that module and squished them around a bit and stuffed them in here. =item L =item L I refactored this module and renamed it L, which is now included in this distro. =back =head1 BUGS All complex software has bugs lurking in it, and this module is no exception. If you find a bug please either email me, or add the bug to cpan-RT. =head1 AUTHOR Stevan Little Estevan@iinteractive.comE Contributions from: Marcus Ramberg Bradley C. Bailey Brian Cassidy Johannes Plunien =head1 COPYRIGHT AND LICENSE Copyright 2007-2010 by Infinity Interactive, Inc. L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut