Skip to content

Commit 03ec98a

Browse files
author
Greg Bowler
committed
Simplify loop timer ordering
1 parent 0887374 commit 03ec98a

4 files changed

Lines changed: 63 additions & 11 deletions

File tree

src/Loop.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ public function waitUntil(float $waitUntilEpoch):void {
5757
);
5858
}
5959

60-
private function triggerNextTimers():int {
60+
// TODO: The epochList is a perfect candidate for one of SPL's Iterators.
61+
// Probably the MultipleIterator...
62+
public function getTimerOrder() {
6163
$epochList = [];
6264

6365
// Create a list of all timers that have a next run time.
@@ -67,17 +69,22 @@ private function triggerNextTimers():int {
6769
}
6870
}
6971

70-
// If there are no more timers to run, return early.
71-
if(empty($epochList)) {
72-
return 0;
73-
}
74-
7572
// Sort the epoch list so that they are in order of next run time.
7673
usort(
7774
$epochList,
7875
fn($a, $b) => $a[0] < $b[0] ? -1 : 1
7976
);
8077

78+
return $epochList;
79+
}
80+
81+
private function triggerNextTimers():int {
82+
$epochList = $this->getTimerOrder();
83+
// If there are no more timers to run, return early.
84+
if(empty($epochList)) {
85+
return 0;
86+
}
87+
8188
// Wait until the first epoch is due, then trigger the timer.
8289
$this->waitUntil($epochList[0][0]);
8390
$this->trigger($epochList[0][1]);

src/Timer/Timer.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public function __construct() {
1717
$this->callbackList = [];
1818
}
1919

20-
public function addCallback(callable $callback):void {
21-
$this->callbackList[] = $callback;
22-
}
20+
// public function addCallback(callable $callback):void {
21+
// $this->callbackList[] = $callback;
22+
// }
2323

2424
public function getNextRunTime():?float {
2525
return $this->triggerTimeQueue[0] ?? null;

test/phpunit/LoopTest.php

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function testWaitUntilNegative() {
3434
$numCalls = 0;
3535

3636
$sut = new Loop();
37-
$sut->setSleepFunction(function(int $milliseconds) use (&$numCalls) {
37+
$sut->setSleepFunction(function() use (&$numCalls) {
3838
$numCalls++;
3939
});
4040

@@ -93,4 +93,48 @@ public function testRunWithTimerNoNextRunTime() {
9393

9494
self::assertEquals(0, $sut->getTriggerCount());
9595
}
96+
97+
public function testGetTimerList() {
98+
$epoch = microtime(true);
99+
100+
$timer1 = self::createMock(Timer::class);
101+
$timer1->method("getNextRunTime")
102+
->willReturn($epoch + 1, null);
103+
$timer2 = self::createMock(Timer::class);
104+
$timer2->method("getNextRunTime")
105+
->willReturn($epoch + 2, null);
106+
107+
$sut = new Loop();
108+
$sut->setSleepFunction(function() {});
109+
$sut->addTimer($timer1);
110+
$sut->addTimer($timer2);
111+
112+
$timerOrder = $sut->getTimerOrder();
113+
self::assertSame($timer1, $timerOrder[0][1]);
114+
self::assertSame($timer2, $timerOrder[1][1]);
115+
}
116+
117+
/**
118+
* The only difference here to the test above is that timer1 is set to
119+
* be due after timer2, so the order of the timers will be different.
120+
*/
121+
public function testGetTimerListOutOfOrder() {
122+
$epoch = microtime(true);
123+
124+
$timer1 = self::createMock(Timer::class);
125+
$timer1->method("getNextRunTime")
126+
->willReturn($epoch + 2, null);
127+
$timer2 = self::createMock(Timer::class);
128+
$timer2->method("getNextRunTime")
129+
->willReturn($epoch + 1, null);
130+
131+
$sut = new Loop();
132+
$sut->setSleepFunction(function() {});
133+
$sut->addTimer($timer1);
134+
$sut->addTimer($timer2);
135+
136+
$timerOrder = $sut->getTimerOrder();
137+
self::assertSame($timer2, $timerOrder[0][1]);
138+
self::assertSame($timer1, $timerOrder[1][1]);
139+
}
96140
}

test/phpunit/Timer/IndividualTimerTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
namespace Gt\Async\Test\Timer;
33

44
use Gt\Async\Timer\IndividualTimer;
5+
use PHPUnit\Framework\TestCase;
56

6-
class IndividualTimerTest extends \PHPUnit\Framework\TestCase {
7+
class IndividualTimerTest extends TestCase {
78
public function testConstructWithFutureTime() {
89
$epoch = microtime(true);
910
$epochPlus50ms = $epoch + 0.05;

0 commit comments

Comments
 (0)