1
0
mirror of https://github.com/danog/loop.git synced 2024-11-26 20:04:44 +01:00

Fix edge cases

This commit is contained in:
Daniil Gentili 2023-01-23 16:05:36 +01:00
parent 4b2a24e3db
commit 75ff0b2df8
3 changed files with 93 additions and 20 deletions

View File

@ -66,8 +66,9 @@ abstract class Loop implements Stringable
return false;
}
$this->running = true;
$this->paused = true;
\assert($this->resume());
$this->startedLoop();
$this->resume();
return true;
}
/**
@ -89,7 +90,7 @@ abstract class Loop implements Stringable
if ($this->resumeImmediate) {
$storedWatcherId = $this->resumeImmediate;
EventLoop::cancel($storedWatcherId);
$this->resumeTimer = null;
$this->resumeImmediate = null;
}
if ($this->paused) {
$this->exitedLoop();
@ -102,17 +103,18 @@ abstract class Loop implements Stringable
private function loopInternal(): void
{
$this->paused = false;
if (!$this->running) {
$this->exitedLoopInternal();
return;
}
\assert($this->running);
try {
$timeout = $this->loop();
} catch (\Throwable $e) {
$this->exitedLoopInternal();
throw $e;
}
if (!$this->running || $timeout === self::STOP) {
if (!$this->running) {
$this->exitedLoopInternal();
return;
}
if ($timeout === self::STOP) {
$this->exitedLoopInternal();
return;
}
@ -139,7 +141,7 @@ abstract class Loop implements Stringable
if ($this->resumeImmediate) {
$storedWatcherId = $this->resumeImmediate;
EventLoop::cancel($storedWatcherId);
$this->resumeTimer = null;
$this->resumeImmediate = null;
}
$this->exitedLoop();
}

View File

@ -104,11 +104,11 @@ class GenericTest extends AsyncTestCase
/**
* Fixture assertions for started loop.
*/
private function fixtureStarted(Loop&LoggingPauseInterface $loop): void
private function fixtureStarted(Loop&LoggingPauseInterface $loop, int $offset = 1): void
{
$this->assertTrue($loop->isRunning());
$this->assertEquals(1, $loop->startCounter());
$this->assertEquals(0, $loop->endCounter());
$this->assertEquals($offset, $loop->startCounter());
$this->assertEquals($offset-1, $loop->endCounter());
}
/**
* Run fixture assertions.
@ -123,20 +123,23 @@ class GenericTest extends AsyncTestCase
$loop = new class($closure, Fixtures::LOOP_NAME) extends GenericLoop implements LoggingPauseInterface {
use LoggingPause;
};
$expectedRunCount = 0;
$this->assertEquals(Fixtures::LOOP_NAME, "$loop");
$this->assertFalse($loop->isRunning());
$this->assertEquals(0, $loop->startCounter());
$this->assertEquals(0, $loop->endCounter());
$this->assertEquals(0, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(0, $loop->getPauseCount());
$loop->start();
$this->assertTrue($loop->start());
delay(0.003);
$this->fixtureStarted($loop);
$expectedRunCount++;
$this->assertEquals(1, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(1, $loop->getPauseCount());
$this->assertEquals(0, $loop->getLastPause());
@ -144,29 +147,32 @@ class GenericTest extends AsyncTestCase
$this->assertTrue($loop->resume());
delay(0.002);
$this->fixtureStarted($loop);
$expectedRunCount++;
$this->assertEquals(2, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(2, $loop->getPauseCount());
$this->assertEquals(0.1, $loop->getLastPause());
delay(0.048);
$this->fixtureStarted($loop);
$this->assertEquals(2, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(2, $loop->getPauseCount());
$this->assertEquals(0.1, $loop->getLastPause());
delay(0.060);
$this->fixtureStarted($loop);
$expectedRunCount++;
$this->assertEquals(3, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(3, $loop->getPauseCount());
$this->assertEquals(0.1, $loop->getLastPause());
$this->assertTrue($loop->resume());
delay(0.003);
$expectedRunCount++;
$this->assertEquals(4, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(4, $loop->getPauseCount());
$this->assertEquals(0.1, $loop->getLastPause());
@ -175,9 +181,10 @@ class GenericTest extends AsyncTestCase
} else {
$pauseTime = GenericLoop::STOP;
$this->assertTrue($loop->resume());
$expectedRunCount++;
}
delay(0.002);
$this->assertEquals($stopSig ? 4 : 5, $runCount);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(4, $loop->getPauseCount());
$this->assertEquals(0.1, $loop->getLastPause());
@ -187,6 +194,70 @@ class GenericTest extends AsyncTestCase
$this->assertFalse($loop->isRunning());
$this->assertFalse($loop->stop());
$this->assertFalse($loop->resume());
// Restart loop
$pauseTime = GenericLoop::PAUSE;
$this->assertTrue($loop->start());
delay(0.003);
$this->fixtureStarted($loop, 2);
$expectedRunCount++;
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(5, $loop->getPauseCount());
$this->assertEquals(0.0, $loop->getLastPause());
if ($stopSig) {
$this->assertTrue($loop->stop());
} else {
$pauseTime = GenericLoop::STOP;
$this->assertTrue($loop->resume());
$expectedRunCount++;
}
delay(0.002);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(5, $loop->getPauseCount());
$this->assertEquals(0.0, $loop->getLastPause());
$this->assertEquals(2, $loop->startCounter());
$this->assertEquals(2, $loop->endCounter());
$this->assertFalse($loop->isRunning());
$this->assertFalse($loop->stop());
$this->assertFalse($loop->resume());
// Restart loop and stop it immediately
$pauseTime = GenericLoop::PAUSE;
$this->assertTrue($loop->start());
$this->assertTrue($loop->stop());
delay(0.003);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(5, $loop->getPauseCount());
$this->assertEquals(0.0, $loop->getLastPause());
$this->assertEquals(3, $loop->startCounter());
$this->assertEquals(3, $loop->endCounter());
$this->assertFalse($loop->isRunning());
$this->assertFalse($loop->stop());
$this->assertFalse($loop->resume());
// Restart loop with delay and stop it immediately
$pauseTime = 1.0;
$this->assertTrue($loop->start());
$this->assertTrue($loop->stop());
delay(0.003);
$this->assertEquals($expectedRunCount, $runCount);
$this->assertEquals(5, $loop->getPauseCount());
$this->assertEquals(0.0, $loop->getLastPause());
$this->assertEquals(4, $loop->startCounter());
$this->assertEquals(4, $loop->endCounter());
$this->assertFalse($loop->isRunning());
$this->assertFalse($loop->stop());
$this->assertFalse($loop->resume());
}
/**

View File

@ -131,7 +131,7 @@ class PeriodicTest extends AsyncTestCase
$this->assertEquals(0, $runCount);
$loop->start();
$this->assertTrue($loop->start());
delay(0.002);
$this->fixtureStarted($loop);