Бэкграунд
Рискую получить много критики в комментариях. Однако, мне очень интересно узнать, что думают люди о расширении, которое я недавно закончил писать. Возможно, кто-то протестирует, и расширение станет «beta-стабильным».
Речь идёт о расширении PECL eio, предоставляющем интерфейс к библиотеке libeio.
libeio
На всякий случай, приведу небольшое описание libeio. Это библиотека С для которая запускает системные вызовы(в основном POSIX) в отдельных потоках. Цель библиотеки — полностью неблокирующее ПО, которое может пригодиться на игровых серверах, как пишет автор библиотеки, М.Леман:
"...in a game server, you would not want to freeze for a few seconds just because the server is running a backup and you happen to call readdir."
Т.е. такие вызовы, как open, read, write, close, readahead, truncate, rename, sendfile, statvfs и т.п. в libeio запускаются в отдельных потоках.
Документация libeio непосредственно не отвергает Windows. Написано, что если соответствующего вызова в библиотеке нет, то libeio эмулирует этот вызов. Однако, в исходном коде практически нет ничего для того, чтобы собрать (обычным образом) код в Windows. У меня такое чувство, что автор подумывал о поддержке Windows, но впоследствии отказался от этой идеи.
Расширение eio
В расширении выполняются вызовы libeio. Для того, чтобы инициировать выполнение ряда вызовов libeio, нужно циклически вызывать eio_poll(). Для этого в PHP экспортирована одноимённая функция. Дополнительно реализован цикл событий в виде функции eio_event_loop(), IPC которой выполнен на основе семафоров. При желании пользователь может выполнить собственный цикл событий существующими средствами PHP(Например, при помощи глобальных переменных[лучше только в CLI] или тех же семафоров с использованием расширения Semaphore).
Документация: http://www.php.net/eio.
Установка
libeio:
$ touch ~/.cvspass
$ cvs -z3 -d :pserver:anonymous@cvs.schmorp.de/schmorpforge co libeio
$ cd libeio
$ ./autogen.sh
$ ./configure
$ make
$ su -
# make install
eio:
$ wget 'http://pecl.php.net/get/eio' -O eio.tgz
$ tar xzvf eio.tgz && cd eio-*
$ phpize
$ ./configure --with-eio # further optional parameters(--enable-eio-debug recommended for first use) ...
$ make && make test
$ su -
# make install
После этого записываем в конфиг php.ini
extension=eio.so
перезапускаем Веб-сервер, если это не CLI.
Если в Gentoo возникают проблемы вроде
libtool: Version mismatch error. This is libtool 2.4, but the
libtool: definition of this LT_INIT comes from an older release.
libtool: You should recreate aclocal.m4 with macros from libtool 2.4
libtool: and run autoconf again.
make: *** [libevent.lo] Error 63
то следующие команды помогут:
$ phpize
$ aclocal && libtoolize --force && autoreconf
$ ./configure --with-eio # further optional parameters(--enable-eio-debug recommended for first use) ...
$ make
# дальше как обычно
Вы также можете воспользоваться пакетами libeio, которые я собрал для следующих дистрибутивов:
Debian_6.0 i586, x86_64
RedHat_RHEL-6 i586, x86_64
openSUSE_11.4 i586, x86_64
xUbuntu_10.04 i586, x86_64
xUbuntu_11.10 i586, x86_64
К сожалению, автор libeio предлагает лишь CVS.
Однако, eio можно установить проще:
# pecl install eio # для stable
# pecl install eio-beta # для beta
# pecl install eio-alpha # для alpha
В качестве альтернативы, можно взять самое свежее из SVN:
$ svn co https://svn.php.net/repository/pecl/eio/trunk eio && cd eio
# pecl install --force package.xml
Последнюю команду нужно дать с правами root
Наконец
Спасибо за внимание. Буду рад любым предложениям по дополнению/изменению API.
P.S.
Это eio далось непросто.
UPDATE
В результате работы с автором libevent:
добавлено: event_priority_set
добавлено: поддержка числовых дескрипторов в event_set
добавлено: поддержка числовых дескрипторов в event_buffer_new
Собственно в eio добавлена поддержка файлового дескриптора, который может быть исопльзован для эффективной связки с libevent, правда, пока только в SVN(см. ниже).
Связка с приоритетами(не прямо таки реальный пример, но кому нужно напишет реальный;):
<?php
function my_eio_poll($fd, $events, $arg) {
/* Some libevent regulation might go here .. */
if (eio_nreqs()) {
eio_poll();
}
/* .. and here */
}
function my_nop_cb($d, $r) {
var_dump($r); var_dump($d);
}
$base = event_base_new();
$event = event_new();
$fd = eio_get_event_stream();
var_dump($fd);
eio_nop(EIO_PRI_DEFAULT, "my_nop_cb", "nop data");
/* some other eio_* calls here ... */
// set event flags
event_set($event, $fd, EV_READ /*| EV_PERSIST*/, "my_eio_poll", array($event, $base));
// Set event priorities
event_base_priority_init($base, 10);
// set event base
event_base_set($event, $base);
// This one is my patch to libevent. Tony should apply it soon
echo "setting priority...\n";
var_dump(event_priority_set($event, 2));
// enable event
event_add($event);
// start event loop
event_base_loop($base);
/* The same kind of stuff is available via buffered libevent API*/
?>
SVN:
svn.php.net/repository/pecl/libevent/trunk
svn.php.net/repository/pecl/eio/trunk