Режимы работы периодических наблюдателей
Наблюдатели EvPeriodic работают в разных режимах
в зависимости от значения параметров offset
,
interval
и reschedule_cb
.
-
Абсолютный таймер. В этом режиме
interval
=0
,reschedule_cb
=null
. Таймер просто сработает один раз в заданное вoffset
время. Он не компенсирует скачки времени и если указанно сработать в 1 Января 2014, то он сработает когда системное время будет равно или больше этого значения. -
Таймер с фиксированным интервалом. В этом режиме
interval
>0
, аreschedule_cb
=null
. Каждое последующее срабатывание будет ровно черезoffset
+N
*interval
(гдеN
- целое число), не взирая на скачки времени.Это можно использовать для создания таймеров, которые не расходятся с системным временем:
<?php
$hourly = EvPeriodic(0, 3600, NULL, function () {
echo "один раз в час\n";
});
?>3600
секунд. Это означает, что callback-функция будет вызвана только когда системные часы покажут полный час (UTC).В этом режиме, EvPeriodic будет пытаться запустить callback-функцию в следующее доступное время, когда time =
offset
(mod
interval
), независимо от скачков времени. -
Режим ручного переопределения времени срабатывания. В этом режиме
reschedule_cb
является корректным параметром типа callable.interval
иoffset
игнорируются. Вместо этого, при каждом срабатывании, наблюдатель запускает callback-функцию (reschedule_cb
) с двумя аргументами, ссылкой на наблюдателя и временем.Эта callback-функция никогда не должна останавливать или уничтожать этот, или какой-либо другой периодический наблюдатель и не должна вызывать функции и методы событийного цикла. Для остановки можно вернуть очень большое число, например,
1e30
, и остановить наблюдатель за пределами этой функции. Для этого можно использовать наблюдателей EvPrepare.Эта функция должна вернуть следующее время срабатывания, основываясь на переданном значении времени (то есть самое маленькое значение времени больше или равно второму аргументу). Обычно она вызывается перед тем, как будет вызвана основная callback-функция наблюдателя, но может и позже.
Пример #1 Использование наблюдателя с ручным переопределением времени срабатывания
<?php
// Срабатывать каждые 10.5 секунд
function reschedule_cb ($watcher, $now) {
return $now + (10.5. - fmod($now, 10.5));
}
$w = new EvPeriodic(0., 0., "reschedule_cb", function ($w, $revents) {
echo time(), PHP_EOL;
});
Ev::run();
?>