Swoole Timer

Notice: ext-swoole is supported until v4.7.1, use ext-openswoole >= v4.7.1. Latest version: pecl install openswoole-4.8.1

A timer can be used to schedule a task to be executed at certain interval/period.

It is similar to Swoole\Server->after which is used to schedule a task to be executed one-time after waiting for a specified amount of time, which also acts like the JavaScript equivalent 'setTimeout'.

How do Timers work?

The timer is accurate down to milliseconds and is based on epoll_wait and timerfd. It can support a large number of timers and is closely related to the event loop. In the event of synchronous I/O Swoole will use settimer (a Linux function used to manage interval timers) to run a outside task to prevent blocking and use the Swoole Manager and TaskWorker to achieve this. For asynchronous I/O, Swoole will use epoll_wait, 'kevent', poll and select functions to implement timer tasks which can be run within a event loop.

Timer Performance

Swoole Timers are all operated in memory, so execution and management is extremely fast, there is no I/O interaction in order to create or destroy a Timer. To implement Timers, Swoole uses the smallest data heap structure possible, so it has a small memory footprint.

You can checkout the performance test for Timers from the timer.php script, this performance test will create and clear thousands of timer tasks at the same time.

Other Differences

Swoole Timers does not use pcntl_alarm which is from the PHP core, instead Swoole uses more efficient Linux and C++ functions (see above) and this is because of the following reasons:

  • With pcntl_alarm you can only create a timer based on seconds, Swoole goes down to milliseconds
  • You can only set one timer with pcntl_alarm whereas, Swoole allows you to set multiple timers at once
  • With pcntl_alarm it is not very efficient and is dependent on declare(ticks = 1)

Zero Millisecond Timer

With Timers you cannot set 0 as the timeout interval/period, to achieve the same functionality as setTimeout(func, 0) which is what you can do in JavaScript to execute a task asynchronously or as soon as possible, you can use Swoole\Event::defer:

<?php

Swoole\Event::defer(function () {
  echo "hello\n";
});

Methods

Timer Alias

We recommend you use the namespace method of accessing the timer but there do exist a function style for each main method:

  • Swoole\Timer::tick(): swoole_timer_tick()
  • Swoole\Timer::after(): swoole_timer_after()
  • Swoole\Timer::clear(): swoole_timer_clear()

Quick Start Example

<?php

function run($timerid, $param) {
    var_dump($timerid);
    var_dump($param);
}

// Every 1s, execute the run function
Swoole\Timer::tick(1000, "run", ["param1", "param2"]);

// After 5s execute the run function, only once
Swoole\Timer::after(5000, "run", ["param3", "param4"]);