Skip to content

Commit 1e498d9

Browse files
authored
Merge pull request #100 from clue-labs/ticks
Documentation and examples for deferred execution via futureTick()
2 parents d914432 + ac541bf commit 1e498d9

7 files changed

+126
-2
lines changed

README.md

+28-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,34 @@ All of the loops support these features:
116116
* File descriptor polling
117117
* One-off timers
118118
* Periodic timers
119-
* Deferred execution of callbacks
119+
* Deferred execution on future loop tick
120+
121+
### futureTick()
122+
123+
The `futureTick(callable $listener): void` method can be used to
124+
schedule a callback to be invoked on a future tick of the event loop.
125+
126+
This works very much similar to timers with an interval of zero seconds,
127+
but does not require the overhead of scheduling a timer queue.
128+
129+
Unlike timers, callbacks are guaranteed to be executed in the order they
130+
are enqueued.
131+
Also, once a callback is enqueued, there's no way to cancel this operation.
132+
133+
This is often used to break down bigger tasks into smaller steps (a form of
134+
cooperative multitasking).
135+
136+
```php
137+
$loop->futureTick(function () {
138+
echo 'b';
139+
});
140+
$loop->futureTick(function () {
141+
echo 'c';
142+
});
143+
echo 'a';
144+
```
145+
146+
See also [example #3](examples).
120147

121148
## Install
122149

examples/03-ticks.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
require __DIR__ . '/../vendor/autoload.php';
4+
5+
$loop = React\EventLoop\Factory::create();
6+
7+
$loop->futureTick(function () {
8+
echo 'b';
9+
});
10+
$loop->futureTick(function () {
11+
echo 'c';
12+
});
13+
echo 'a';
14+
15+
$loop->run();

examples/91-benchmark-ticks.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use React\EventLoop\Factory;
4+
5+
require __DIR__ . '/../vendor/autoload.php';
6+
7+
$loop = Factory::create();
8+
9+
$n = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
10+
11+
for ($i = 0; $i < $n; ++$i) {
12+
$loop->nextTick(function () { });
13+
}
14+
15+
$loop->run();

examples/92-benchmark-timers.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use React\EventLoop\Factory;
4+
5+
require __DIR__ . '/../vendor/autoload.php';
6+
7+
$loop = Factory::create();
8+
9+
$n = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
10+
11+
for ($i = 0; $i < $n; ++$i) {
12+
$loop->addTimer(0, function () { });
13+
}
14+
15+
$loop->run();

examples/93-benchmark-ticks-delay.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use React\EventLoop\Factory;
4+
5+
require __DIR__ . '/../vendor/autoload.php';
6+
7+
$loop = Factory::create();
8+
9+
$ticks = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
10+
$tick = function () use (&$tick, &$ticks, $loop) {
11+
if ($ticks > 0) {
12+
--$ticks;
13+
//$loop->addTimer(0, $tick);
14+
$loop->nextTick($tick);
15+
} else {
16+
echo 'done';
17+
}
18+
};
19+
20+
$tick();
21+
22+
$loop->run();
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use React\EventLoop\Factory;
4+
5+
require __DIR__ . '/../vendor/autoload.php';
6+
7+
$loop = Factory::create();
8+
9+
$ticks = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
10+
$tick = function () use (&$tick, &$ticks, $loop) {
11+
if ($ticks > 0) {
12+
--$ticks;
13+
//$loop->nextTick($tick);
14+
$loop->addTimer(0, $tick);
15+
} else {
16+
echo 'done';
17+
}
18+
};
19+
20+
$tick();
21+
22+
$loop->run();

src/LoopInterface.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,15 @@ public function isTimerActive(TimerInterface $timer);
8888
/**
8989
* Schedule a callback to be invoked on a future tick of the event loop.
9090
*
91-
* Callbacks are guaranteed to be executed in the order they are enqueued.
91+
* This works very much similar to timers with an interval of zero seconds,
92+
* but does not require the overhead of scheduling a timer queue.
93+
*
94+
* Unlike timers, callbacks are guaranteed to be executed in the order they
95+
* are enqueued.
96+
* Also, once a callback is enqueued, there's no way to cancel this operation.
97+
*
98+
* This is often used to break down bigger tasks into smaller steps (a form of
99+
* cooperative multitasking).
92100
*
93101
* @param callable $listener The callback to invoke.
94102
*/

0 commit comments

Comments
 (0)