Pull to refresh
22
0
Руслан Османов @osmanov

Release Engineer

Send message
Планировщик, для которого был написан пример, может быть выполнен
при помощи расширения ev:

<?php
$w1 = new EvIdle(function ($w) {
	(--$w->data[0] <= 0) and $w->stop();
	
	echo "Task 1, i = ", $w->data[0], PHP_EOL;
}, array (10));

$w2 = new EvIdle(function ($w) {
	(--$w->data[0] <= 0) and $w->stop();
	
	echo "Task 2, i = ", $w->data[0], PHP_EOL;
}, array (5));

Ev::run();
?>


Небольшие примеры.

Слежение за доступностью сокета, файла или другого узла может быть выполнено с помощью
EvIo. Асинхронные файловые операции
можно также выполнять, например, через eio_read, eio_write, eio_sendfile и др.
релиз 0.5.0 beta pecl.php.net/package/eio

Refact: libeio upgraded
Fix: bug #62392 where eio_*stat functions didn't return st_size
Fix: package.xml referenced to some nonexistent files
Fix: garbage in result arg of the callbacks in case of error
Change: warn about failed op in cb only when compiled with debug support
Add: test for stat on nonexistent files
Add: sockets support(eio_sendfile, eio_readahead etc.), enabled by default
Add: eio_seek function
Change: numeric fd arguments are now mixed(stream, Socket, or number)
эмм…
Я делал для простых задач вроде бэкапа, копирования с одного сервера на другой.
В кроне запускается скрипт, который запускает разного рода задачи:
— бэкап сайтов
— копирование сайта с одного хоста на другой
— восстановление бэкапа сайта

Бывает, что на некоторых командах оно просто стопорится, и вся очередь ждёт когда, например, закончится копирование или архивация. Тут как раз удобно запустить в отдельном потоке и пойти дальше.
Да, до того, как решил встроить было много проблем. В частности, на 32-битных платформах расширение вело себя очень непредсказуемо. Как выяснилось, потому просто, что в одной из структур libeio было поле типа off_t, размер которого на разных платформах ОС выбирает по-разному, устанавливает FILE_OFFSET_BITS либо 4, либо 8. Например у меня в Debian было 4, а в openSUSE — 8.

После долгих общений с автором libeio и поисков нестандартных решений, автор мне пишет,
что вообще то самый нормальный способ — встроить libeio в расширение, как он это уже сделал в модуле для Perl.
А просто libeio встроен в расширение ;)
Т.е. код libeio включается в код расширение, компилируется вместе с ним :)
Примеры вроде были.
docs.php.net/manual/en/eio.examples.php#example-3308

На самом деле конечно очень нехватает цикла событий типа libev…
Не хочу постить что попало. Хорошенько отдебажу и выложу.
Прогресс есть, но не в плане ООП. В текущей 0.4.0 beta исправлены многочисленные ошибки, а libeio больше не нужно устанавливать отдельно — он встроен в расширение. Т.е. достаточно дать команду
sudo pecl install eio-beta

Про ООП думал. Просто не нахожу большой выгоды. Потому что eio по большому счёту полезен в сочетании с некоторым циклом событий, таким как libevent или libev. В данный момент пишу расширение для последнего, где как раз будет ООП во всей красе. Тогда большая часть проблем инкапсуляции ляжет на классы ev.
Вот пакеты 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

Пришлось собрать за автора.

eio конечно можно было бы установить через `pecl install eio`, но версия alpha этого скорее всего не позволит. Поэтому я бы установил вручную. В качестве альтернативы, можно взять самое свежее:
$ svn co svn.php.net/repository/pecl/eio/trunk eio && cd eio
# pecl install --force package.xml

Последнюю команду нужно дать с правами root
читайте update в статье
У меня идея: вынести внутреннюю переменную, используемую для переключения колбеков want-poll/done-poll в PHP;
тем самым дать возможность libevent понять, когда libeio вызвала want-poll callback. Т.е. это может выглядеть так:

1. Новая функция eio_get_fd возвращает нечто, что может «прослушивать» libevent, например файловый дескриптор:
<?php $fd = eio_get_fd(); ?>

2. want_poll и done_poll внутри пишут в… назовём это «дескриптором»… дескриптор и читают из него по байту, как и прежде.
Ничего не двинется дальше, пока что-то или кто-то не вызовет eio_poll().

3. Когда байт пришел в дескриптор, libevent может вызвать eio_poll() инициируя дальнейшее выполнение задач.

4. libeio вызывает внутри done_poll callback. Последний дописывает что нужно куда нужно, и нормальный цикл завершается.
chmod может быть не часто придется запускать асинхронно. А вот, например, readdir, read, write, readahead, truncate, sendfile и др. возможно иногда полезно запускать асинхронно
eio пока сырой в том смысле, что просто так реализовать асинхронный non-polling-mode можно только через внешний цикл событий. Например, при помощи libevent:
while(!$stop_signal){
event_base_loop($event_base, EVLOOP_ONCE|EVLOOP_NONBLOCK);
if (eio_nreqs()) eio_poll();
}


eio_poll() толкает libeio; возвращает мгновенно, если работы нет; если работа есть(запланированные запросы типа eio_custom, eio_open и т.п.), то может выполнить разом несколько.
eio_nreqs() возвращает количество невыполненных запросов.

Это можно использовать в приложениях/демонах/серверах, которые написаны на PHP с использованием расширения libevent и асинхронно работают с сетью. Если в этих приложениях есть необходимость работы с диском, то с помощью eio это можно делать в асинхронном стиле. Выще приведён простейший код интеграции. Можно интегрировать
через таймер (опрашивать по таймеру). Именно так мы пока собираемся его использовать.

По поводу API.
Можно также группировать запросы при помощи eio_grp, eio_grp_add и отменять их через eio_grp_cancel.

eio_grp создает группу, возвращая ресурс группы;
eio_grp_cancel отменяет все запросы группы.
eio_cancel может отменить как сам запрос группы, так и любой другой запрос eio_*
eio_grp_add добавляет запрос eio_* в группу.

Вот примеры в режиме поллинга(пока).

Конечно, связка с libev так и напрашивается. Но присоединять libev к eio в этом расширении нехорошо. Возможно, последует расширение ev. Тем не менее, будет отдельный воркер или т.п… Возможно, это будет выглядеть примерно так:

Eio — класс
Eio::__construct($internal_loop=TRUE/*использовать внутренний цикл событий*/)
Eio::loop() — цикл событий опосредованный внутренним watcher'ом.

для использования внешним расширением, например libevent:
Eio::poll_fileno — дескриптор файла, который может применяться в качестве триггера событий(в него можно писать и из него можно читать)
Eio::signal() — записать октет/байт в poll_fileno
Eio::drain() — прочитать октет/байт из poll_fileno
а в Gentoo? ;) Там только самому писать ebuild.
А вообще конечно checkinstall отличная утилита. Правда иногда самому приходится создавать директории для успешного завершения `make install`
Здесь до версии 0.2.0a тоже висло. Сейчас вроде в порядке. Исключения пока не поддерживает, но можно добавить.
Кстати, нужен ли тут OOP API?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity