Reading from a named pipe / fifo (final version)

Max nginxyz at mail.ru
Sun Jan 22 02:04:04 UTC 2012


21 января 2012, 21:41 от "takigama" <nginx-forum at nginx.us>:
> 
> Personally, the way i'd do it is to write a bit of php (or python, perl,
> etc) called via fast cgi [...]

Thanks for the suggestion, but using FastCGI is not an option for
many reasons. The most elegant solution I could come up with
without hacking nginx involves embedded Perl like this:

===<FIFOReader.pm>===
package FIFOReader;

use nginx;

sub handler {
    my $r = shift;
    alarm 5;
    open(FIFO, "</path/to/fifo") or return 444;
    alarm 0;
    while (<FIFO>) {
        $r->print($_);
    }
    $r->rflush();
    close(FIFO);
    return OK;
}

1;
__END__
===</FIFOReader.pm>===

===<nginx.conf>===
http {
  perl_modules perl.modules/;
  perl_require FIFOReader.pm;
  
  server {
    location ~ ^/readfifo {
      ssi on;
      perl FIFOReader::handler;
    }
  }
}
===</nginx.conf>===

===<readfifo>===
<!-- # perl sub="FIFOReader::handler" -->
===</readfifo>===

FIFOReader.pm is located in $nginx_conf_dir/perl.modules/
readfifo is located in $document_root/

In the FIFOReader Perl module I first set the alarm to allow
the blocking open() call 5 seconds to open the FIFO. After
5 seconds the blocking open() call gets interrupted and
nginx returns code 444, which tears down the connection
without sending any kind of response code, so there is
no need to check for response codes - the client gets
either nothing or the data from the FIFO.

If the blocking open() call succeeds before the timeout,
the alarm is turned off and the data is read from
the FIFO and passed on to the client, after which the
FIFO is closed and the OK code is returned by nginx.

There is no additional alarm to prevent read timeouts
(before while (<FIFO>)) because that is left up to the
client by design.

Another side benefit of this approach is that it doesn't
require additional processes (such as FastCGI wrappers),
so there is no need to supervise additional processes to
make sure they're around. The embedded Perl module
will work for as long as nginx is running.

I have started working on a FIFO module to allow per-location
FIFO opening and reading. If I get it to production quality I'll
post my patches to the list.

Max


More information about the nginx mailing list