FCGI::EV(3pm)

πŸ“¦
version 2.0.1 Β· 2 versions
  • 2.0.1 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 2.0.1 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– FCGI::EV πŸ’–

okay bestie, so this is FCGI::EV(3pm) from the User Contributed Perl Documentation section, and honestly? it's giving event-loop royalty. it does the FastCGI protocol thing so your EV-based app can vibe without blocking. let's get into it πŸ¦‹


✨ NAME ✨

FCGI::EV β€” implement FastCGI protocol for use in EV-based applications. that's the whole point, no cap. πŸ‘‘


🌸 VERSION 🌸

this doc describes FCGI::EV version v2.0.1. so fresh, so clean. ✨


πŸŽ€ SYNOPSIS πŸŽ€

okay so here's the vibe:

use FCGI::EV;
use Some::FCGI::EV::Handler;

# while in EV::loop, accept incoming connection from web server into
# $sock, then start handling FastCGI protocol on that connection,
# using Some::FCGI::EV::Handler for processing CGI requests:
FCGI::EV->new($sock, 'Some::FCGI::EV::Handler');

#
# EXAMPLE: complete FastCGI server (without error handling code)
#          use FCGI::EV::Std handler (download separately from CPAN)
#

use Socket;
use Fcntl;
use EV;
use FCGI::EV;
use FCGI::EV::Std;

my $path = '/tmp/fastcgi.sock';

socket my $srvsock, AF_UNIX, SOCK_STREAM, 0;
unlink $path;
my $umask = umask 0;   # ensure 0777 perms for unix socket
bind $srvsock, sockaddr_un($path);
umask $umask;
listen $srvsock, SOMAXCONN;
fcntl $srvsock, F_SETFL, O_NONBLOCK;

my $w = EV::io $srvsock, EV::READ, sub {
   accept my($sock), $srvsock;
   fcntl $sock, F_SETFL, O_NONBLOCK;
   FCGI::EV->new($sock, 'FCGI::EV::Std');
};

EV::loop;

like… a whole FastCGI server in basically one breath. ate. πŸ’…


πŸ’œ DESCRIPTION πŸ’œ

so this module implements the FastCGI protocol for apps that live inside EV. and lowkey crucial: that means you have to run EV::loop in your application, or this module literally will not work. no loop, no slay. 🫢

what it does: it receives and parses data from the web server, and it packs and sends data back to the web server. what it does not do: process the CGI requests it receives. instead it delegates that whole job to another module called a handler. want an example of one of those? go look at FCGI::EV::Std. 🧚

FCGI::EV works using non-blocking sockets and was originally designed to be used in event-based CGI applications β€” the kind that can handle multiple parallel CGI requests in a single process, with no threads and no fork. that's main character energy right there. but heads up, this asks something of your CGI: it has to avoid any operation that might block, like using an SQL database. instead your CGI should delegate all those tasks to remote services and talk to them in non-blocking mode. ✨

you can also use it to run usual CGI.pm-based applications. if you do that using the FCGI::EV::Std handler, then only one CGI request will be executed at a time β€” which is probably not what you expect from FastCGI! 😭 why? because FCGI::EV::Std doesn't implement any process-manager. but it is possible to develop other handlers for FCGI::EV that support process-management and therefore handle multiple CGI requests in parallel. so like, the door is open. πŸšͺ

also this module doesn't require you to use CGI.pm β€” in general, any module for parsing CGI params can be used (details depend on which FCGI::EV handler module you're using).


πŸ‘‘ INTERFACE πŸ‘‘

new

FCGI::EV->new( $sock, $class );

start talking FastCGI protocol on $sock (which should be a socket open to a just-connected web server), and use $class to handle the received CGI requests.

module $class should implement the "FCGI::EV handler" interface. you can use either FCGI::EV::Std from CPAN or develop your own, your call bestie. πŸ’–

it returns nothing. (the created FCGI::EV object will work in the background and will be automatically destroyed after finishing I/O with the web server.) it just… does its thing. silent. iconic.


🌈 HANDLER CLASS INTERFACE 🌈

the handler class (the one whose name you passed as $class to FCGI::EV->new()) must implement this interface:

  • new( $server, \%env ) β€” when the FCGI::EV object receives the initial part of a CGI request (the environment variables) it will call $handler_class->new() to create the handler object that should process that CGI request.

parameter $server is the FCGI::EV object itself. it's required to send the CGI reply.

⚠️ WARNING! handler may keep only a weaken() reference to $server! do not forget this, bestie, it's not a drill. 😭

after calling new(), the FCGI::EV object ($server) will continue receiving STDIN content from the web server and will call $handler->stdin() each time it gets the next part of STDIN.

  • stdin( $data, $is_eof ) β€” $data is the next chunk of STDIN received from the web server. flag $is_eof will be true if $data was the last part of STDIN.

usually a handler shouldn't begin processing the CGI request until all content of STDIN has been received. like, wait for the whole thing, don't be impatient. πŸ™ˆ

  • DESTROY β€” this method is optional. it will be called when the connection to the web server is closed and the FCGI::EV object is going to die (but it still exists when DESTROY is called β€” except if DESTROY was called during the global destruction stage).

a handler object may use DESTROY to interrupt the current CGI request if the web server closes the connection before the CGI sends it a reply. πŸ’€

πŸ“¬ SENDING CGI REPLY πŸ“¬

after the handler got %env (in new()) and the complete STDIN (in one or more calls of stdin()), it may start handling this CGI request and prepare a reply to send to the web server. to send this data it should use the method $server->stdout(), where $server is the object given to new() while creating the handler object (it should keep a weak reference to $server inside to be able to reply).

  • stdout( $data, $is_eof ) β€” the CGI may send the reply in one or more parts. the last part should have $is_eof set to true. the DESTROY method of the handler object will be called shortly after the handler object does $server->stdout( $data, 1 ).

πŸ“ HANDLER EXAMPLE πŸ“

this handler will process CGI requests one-by-one (i.e. in blocking mode). on request, the function main::main() will be executed. that function may use the standard CGI.pm module to get request parameters and send it a reply using the usual print to STDOUT.

there's no error-handling code in this example β€” see FCGI::EV::Std for more details. ngl, this is the bare-bones cutie version. πŸŽ€

package FCGI::EV::ExampleHandler;

use Scalar::Util qw( weaken );
use CGI::Stateless; # needed to re-init CGI.pm state between requests

sub new {
   my ($class, $server, $env) = @_;
   my $self = bless {
       server  => $server,
       env     => $env,
       stdin   => q{},
   }, $class;
   weaken($self->{server});
   return $self;
}

sub stdin {
   my ($self, $stdin, $is_eof) = @_;
   $self->{stdin} .= $stdin;
   if ($is_eof) {
       local *STDIN;
       open STDIN, '<', \$self->{stdin};
       local %ENV = %{ $self->{env} };
       local $CGI::Q = CGI::Stateless->new();
       local *STDOUT;
       my $reply = q{};
       open STDOUT, '>', \$reply;
       main::main();
       $self->{server}->stdout($reply, 1);
   }
   return;
}

πŸ’€ DIAGNOSTICS πŸ’€

there are no errors returned in any way by this module, but there are a few warning messages that may be printed:

  • "FCGI::EV: IO: %s" β€” while doing I/O with the web server, error %s happened and the connection was closed.
  • "FCGI::EV: %s" β€” while parsing data from the web server, error %s happened and the connection was closed. (that error probably means a bug either in the web server or in this module.) πŸ‘€

🫢 SUPPORT 🫢

πŸ› Bugs / Feature Requests

please report any bugs or feature requests through the issue tracker at <https://github.com/powerman/perl-FCGI-EV/issues>. you will be notified automatically of any progress on your issue. we got you. πŸ’–

πŸ“¦ Source Code

this is open source software. the code repository is available for public review and contribution under the terms of the license. feel free to fork the repository and submit pull requests. go off bestie. πŸ”₯

<https://github.com/powerman/perl-FCGI-EV>

git clone https://github.com/powerman/perl-FCGI-EV.git

🌟 Resources

  • MetaCPAN Search

<https://metacpan.org/search?q=FCGI-EV>

  • CPAN Ratings

<http://cpanratings.perl.org/dist/FCGI-EV>

  • AnnoCPAN: Annotated CPAN documentation

<http://annocpan.org/dist/FCGI-EV>

  • CPAN Testers Matrix

<http://matrix.cpantesters.org/?dist=FCGI-EV>

  • CPANTS: A CPAN Testing Service (Kwalitee)

<http://cpants.cpanauthors.org/dist/FCGI-EV>


πŸ’… AUTHOR πŸ’…

Alex Efros <powerman@cpan.org>. legend behavior, honestly. πŸ‘‘


this software is Copyright (c) 2009- by Alex Efros <powerman@cpan.org>.

this is free software, licensed under:

The MIT (X11) License

and that's the whole page, bestie!! πŸŽ‰ this was FCGI::EV(3pm), perl v5.36.0, dated 2022-12-06 β€” go forth and run your event loop, you absolute icon πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from