[Moscow.pm] [ANN] nginx-perl
Ruslan Zakirov
ruz на bestpractical.com
Ср Ноя 2 15:15:15 UTC 2011
Привет,
Есть в загашнике один асинхронный проект, но пока нету времени к нему
вернуться, но все равно спрошу общие вопросы.
Я еще раньше смотрел на ваш Nginx::Engine краем глаза. Я так понимаю
это новое решение полностью вытеснит необходимость в Nginx::Engine.
Верно?
Судя по всему можно поверх этого дела написать реализацию
AnyEvent::Impl::Nginx. Верно?
2011/11/1 Alexandr Gomoliako <zzz на zzz.org.ua>:
> Hello,
>
> Предлагаю попробовать расширенный встроенный перл.
> Я решил переделать все то, что мне не нравилось в прошлом
> моем модуле, но уже в виде патча для nginx,
>
> Взять в виде дистрибутива можно тут:
> https://github.com/zzzcpan/nginx-perl
>
> Вся документация пока только в этом письме.
>
> Старый API не меняется и практически не тронут:
> http://nginx.org/ru/docs/http/ngx_http_perl_module.html
>
>
> 1. Установка
>
> Сразу советую собрать с новым перлом, использованиe
> памяти в других не обрадует:
> Сейчас это довольно просто:
> % sudo cpan App::perlbrew
> % perlbrew --force install perl-5.14.2
>
> И через пол часа получите перл в
> /home/<user>/perl5/perlbrew/perls/perl-5.14.2/
>
> Теперь nginx, перл там включен сразу, нужно только
> указать, с каким собрать:
> % ./configure
> --with-perl=/home/<user>/perl5/perlbrew/perls/perl-5.14.2/bin/perl
> % make
>
> В дистрибутиве есть готовый конфиг для быстрого старта:
> % mkdir hello/logs
> % ./objs/nginx -p hello
>
> Пример модуля лежит в hello/lib/Hello.pm, конфиг в hello/conf/nginx.conf.
>
>
> 2. Асинхронные ответы
>
> Можно отвечать на запросы асинхронно из другого
> обработчика:
>
> sub handler {
> my $r = shift;
>
> $r->main_count_inc;
>
> # ... здесь создаем обработчики для других событий
>
> return NGX_DONE;
> }
>
> NGX_DONE позволяет не обрабатывать запрос по старому,
> а сразу выйти из обрабтчика и вернуться в event loop.
>
> Чтобы отправить ответ позже, нужно две строчки:
>
> $r->send_special(NGX_HTTP_LAST);
> $r->finalize_request(NGX_OK);
>
> Пример, создать таймер и ответить через секунду:
>
> sub handler {
> my $r = shift;
> $r->main_count_inc;
>
> ngx_timer 1, 0, sub {
> $r->send_http_header("text/html");
> $r->print("Hello\n");
>
> $r->send_special(NGX_HTTP_LAST);
> $r->finalize_request(NGX_OK);
> }
>
> return NGX_DONE;
> }
>
>
> 3. Асинхронные соединения:
>
> - все ошибки устанавливаются в $!,
> - EOF считается ошибкой, можно проверить условием:
> $! == NGX_EOF
> - flow control происходит через return:
> return NGX_READ;
> return NGX_WRITE;
> return NGX_CLOSE;
>
> Чтобы подключиться к какому-то хосту используется
> ngx_connector:
>
> ngx_connector $host, $port, $timeout, sub {
> return NGX_CLOSE if $!;
> my $connection = shift;
> ...
> };
>
> Внутри коннектора можно создавать функции чтения
> и записи:
>
> ngx_writer $buf, $timeout, sub {
> return NGX_CLOSE if $!;
> ...
> return NGX_READ;
> };
>
> ngx_reader $buf, $min, $max, $timeout, sub {
> return NGX_CLOSE if $!;
> ...
> return NGX_CLOSE;
> };
>
> ngx_reader и ngx_writer можно пересоздавать
> внутри сколько угодно раз.
>
> Пример: подключиться к какому-то фтп и считать
> приветствие:
>
> ngx_connector '87.51.34.132', 21, 5, sub {
> return NGX_CLOSE if $!;
>
> my $c = shift;
> my $buf = '';
>
> ngx_reader $c, $buf, 0, 0, 5, sub {
> return NGX_CLOSE if $!;
> return NGX_READ if $buf !~ /\x0a/;
>
> warn "buf = $buf\n";
>
> return NGX_CLOSE;
> };
>
> return NGX_READ;
> };
>
> Более сложный пример можно найти в hello/lib/Hello.pm,
> функция selftest_get. Она отправляет простой http запрос,
> принимает ответ и возвращает результат в колбэк.
>
>
> 4. Подход
>
> Уже наверное понятно, какой подход реализован:
> - все, что вложено -- последовательно
> - все, что подряд -- параллельно
>
> Все переменные хранятся в пэдах, никаких объектов.
> Чтобы не запутаться, лучше так и продолжать, это довольно
> просто:
>
> sub foo ($\$&) {
> my ($arg, $arg_ref, $cb) = @_;
> # ... здесь можно вызывать таймер, коннектор и т.д.
> &$cb();
> }
>
> Вызов:
> foo 1, $buf, sub {
> print $buf;
> };
>
>
> 5. Баги
>
> Модуль довольно большой, так что не без багов.
>
> Будьте осторожны с отправкой ответа два раза, это
> вызовет segfault, потому что $r уже после первого будет
> указывать на осоводившуюся память.
> Со временем пофиксим.
>
>
> На всякий случай прикладываю и в виде патча.
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
--
Best regards, Ruslan.
Подробная информация о списке рассылки nginx-ru