<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/book.ev.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'ev.periodic-modes.php',
    1 => 'Режимы работы периодических наблюдателей',
    2 => 'Режимы работы периодических наблюдателей',
  ),
  'up' => 
  array (
    0 => 'book.ev.php',
    1 => 'Ev',
  ),
  'prev' => 
  array (
    0 => 'ev.watcher-callbacks.php',
    1 => 'Watcher callbacks',
  ),
  'next' => 
  array (
    0 => 'class.ev.php',
    1 => 'Ev',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'reference/ev/periodic-modes.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="ev.periodic-modes" class="chapter">
 <h1 class="title">Режимы работы периодических наблюдателей</h1>

 <p class="simpara">
  Наблюдатели <span class="classname"><a href="class.evperiodic.php" class="classname">EvPeriodic</a></span> работают в разных режимах
  в зависимости от значения параметров <code class="parameter">offset</code>,
  <code class="parameter">interval</code> и <code class="parameter">reschedule_cb</code>.
 </p>
 <ol type="1">
  <li class="listitem">
   <span class="simpara">
    <em>Абсолютный таймер</em>.
    В этом режиме <code class="parameter">interval</code> = <code class="literal">0</code>,
    <code class="parameter">reschedule_cb</code> = <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong>. Таймер просто сработает один раз
    в заданное в <code class="parameter">offset</code> время.
    Он не компенсирует скачки времени и если указанно сработать в
    <em>1 Января 2014</em>, то он сработает когда системное
    время будет равно или больше этого значения.
   </span>
  </li>
  <li class="listitem">
   <span class="simpara">
    <em>Таймер с фиксированным интервалом</em>.
    В этом режиме <code class="parameter">interval</code> &gt; <code class="literal">0</code>, а
    <code class="parameter">reschedule_cb</code> = <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong>. Каждое последующее срабатывание
    будет ровно через <code class="parameter">offset</code> + <strong><code>N</code></strong>
    * <code class="parameter">interval</code> (где <strong><code>N</code></strong> - целое число), не
    взирая на скачки времени.
   </span>
   <p class="para">
    Это можно использовать для создания таймеров, которые не расходятся с системным временем:
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$hourly </span><span style="color: #007700">= </span><span style="color: #0000BB">EvPeriodic</span><span style="color: #007700">(</span><span style="color: #0000BB">0</span><span style="color: #007700">, </span><span style="color: #0000BB">3600</span><span style="color: #007700">, </span><span style="color: #0000BB">NULL</span><span style="color: #007700">, function () {<br />  echo </span><span style="color: #DD0000">"один раз в час\n"</span><span style="color: #007700">;<br />});<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    Это не означает, что между срабатываниями будет всегда ровно
    <code class="literal">3600</code> секунд. Это означает, что callback-функция будет
    вызвана только когда системные часы покажут полный час
    (<em>UTC</em>).
   </p>
   <span class="simpara">
    В этом режиме, <span class="classname"><a href="class.evperiodic.php" class="classname">EvPeriodic</a></span> будет пытаться запустить
    callback-функцию в следующее доступное время, когда
    <var class="varname">time</var> = <code class="parameter">offset</code> (<code class="literal">mod</code>
    <code class="parameter">interval</code>), независимо от скачков времени.
   </span>
  </li>
  <li class="listitem">
   <span class="simpara">
    <em>Режим ручного переопределения времени срабатывания</em>.
    В этом режиме <code class="parameter">reschedule_cb</code> является
    корректным параметром типа <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>.
   </span>
   <span class="simpara">
    <code class="parameter">interval</code> и
    <code class="parameter">offset</code> игнорируются. Вместо этого, при
    каждом срабатывании, наблюдатель запускает callback-функцию
    (<code class="parameter">reschedule_cb</code>) с двумя аргументами,
    ссылкой на наблюдателя и временем.
   </span>
   <span class="simpara">
    Эта callback-функция никогда <em>не должна</em>
    останавливать или уничтожать этот, или какой-либо другой
    периодический наблюдатель и <em>не должна</em>
    вызывать функции и методы событийного цикла. Для остановки
    можно вернуть очень большое число, например, <code class="literal">1e30</code>,
    и остановить наблюдатель за пределами этой функции.
    Для этого можно использовать наблюдателей <span class="classname"><a href="class.evprepare.php" class="classname">EvPrepare</a></span>.
   </span>
   <span class="simpara">
    Эта функция должна вернуть следующее время срабатывания, основываясь на
    переданном значении времени (то есть самое маленькое значение времени
    больше или равно второму аргументу). Обычно она вызывается перед тем, как
    будет вызвана основная callback-функция наблюдателя, но может и позже.
   </span>
   <div class="example" id="example-1">
    <p><strong>Пример #1 Использование наблюдателя с ручным переопределением времени срабатывания</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">// Срабатывать каждые 10.5 секунд<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">reschedule_cb </span><span style="color: #007700">(</span><span style="color: #0000BB">$watcher</span><span style="color: #007700">, </span><span style="color: #0000BB">$now</span><span style="color: #007700">) {<br />   return </span><span style="color: #0000BB">$now </span><span style="color: #007700">+ (</span><span style="color: #0000BB">10.5</span><span style="color: #007700">. - </span><span style="color: #0000BB">fmod</span><span style="color: #007700">(</span><span style="color: #0000BB">$now</span><span style="color: #007700">, </span><span style="color: #0000BB">10.5</span><span style="color: #007700">));<br />}<br /><br /></span><span style="color: #0000BB">$w </span><span style="color: #007700">= new </span><span style="color: #0000BB">EvPeriodic</span><span style="color: #007700">(</span><span style="color: #0000BB">0.</span><span style="color: #007700">, </span><span style="color: #0000BB">0.</span><span style="color: #007700">, </span><span style="color: #DD0000">"reschedule_cb"</span><span style="color: #007700">, function (</span><span style="color: #0000BB">$w</span><span style="color: #007700">, </span><span style="color: #0000BB">$revents</span><span style="color: #007700">) {<br />   echo </span><span style="color: #0000BB">time</span><span style="color: #007700">(), </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br />});<br /><br /></span><span style="color: #0000BB">Ev</span><span style="color: #007700">::</span><span style="color: #0000BB">run</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </li>
 </ol>
</div>
<?php manual_footer($setup); ?>