Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ANN] nginx-perl
- To: nginx-ru@xxxxxxxxx, moscow-pm@xxxxxx
- Subject: [ANN] nginx-perl
- From: Alexandr Gomoliako <zzz@xxxxxxxxxx>
- Date: Tue, 1 Nov 2011 19:48:42 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type:content-transfer-encoding; bh=5I45POtY7kRKr7HzZoTA+b1ytYaLrOWdSApvcu+f7nY=; b=ZEBdgP4j3tEL9nRbWSMQM2HgwnQQjjlE+sn7ls0f+BKdwhsqKnVFnJlKGwil36fOa1 uIZDJp5M7C0Z2RXrX093X3/kzVO1gtRgCg/SLXwa1jCjkbibS42+gbeM5EMNZFTCcWF5 vbfGvrf0rqB9Ozyv1uPEXS0qRte0fX1FokPo8=
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 уже после первого будет
указывать на осоводившуюся память.
Со временем пофиксим.
На всякий случай прикладываю и в виде патча.
_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://mailman.nginx.org/mailman/listinfo/nginx-ru
|