OpenSwoole Timer

Latest version: pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5

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

It is similar to OpenSwoole\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 OpenSwoole will use settimer (a Linux function used to manage interval timers) to run a outside task to prevent blocking and use the OpenSwoole Manager and TaskWorker to achieve this. For asynchronous I/O, OpenSwoole will use epoll_wait, 'kevent', poll and select functions to implement timer tasks which can be run within a event loop.

Timer Performance

OpenSwoole 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, OpenSwoole 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

OpenSwoole Timers does not use pcntl_alarm which is from the PHP core, instead OpenSwoole 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, OpenSwoole goes down to milliseconds
  • You can only set one timer with pcntl_alarm whereas, OpenSwoole 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 OpenSwoole\Event::defer:

<?php

OpenSwoole\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:

  • OpenSwoole\Timer::tick(): swoole_timer_tick()
  • OpenSwoole\Timer::after(): swoole_timer_after()
  • OpenSwoole\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
OpenSwoole\Timer::tick(1000, "run", ["param1", "param2"]);

// After 5s execute the run function, only once
OpenSwoole\Timer::after(5000, "run", ["param3", "param4"]);
Last updated on February 7, 2023