Skip to content

Commit 033dc5f

Browse files
authored
Merge pull request #229 from clue-labs/queue-fibers
Continue internal `Queue` execution also after fiber is suspended
2 parents 1c325e7 + 616495c commit 033dc5f

File tree

3 files changed

+52
-5
lines changed

3 files changed

+52
-5
lines changed

src/Internal/Queue.php

+4-5
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ public function enqueue(callable $task): void
1919
private function drain(): void
2020
{
2121
for ($i = \key($this->queue); isset($this->queue[$i]); $i++) {
22-
try {
23-
($this->queue[$i])();
24-
} finally {
25-
unset($this->queue[$i]);
26-
}
22+
$task = $this->queue[$i];
23+
unset($this->queue[$i]);
24+
25+
$task();
2726
}
2827

2928
$this->queue = [];

tests/Internal/QueueTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,27 @@ public function executesNestedEnqueuedTasks()
3030
$queue->enqueue($task);
3131
}
3232

33+
/**
34+
* @test
35+
* @requires PHP 8.1
36+
*/
37+
public function executesFollowingTasksIfPriorTaskSuspendsFiber()
38+
{
39+
$queue = new Queue();
40+
41+
$fiber = new \Fiber(function () use ($queue) {
42+
$queue->enqueue(function () {
43+
\Fiber::suspend(2);
44+
});
45+
return 1;
46+
});
47+
48+
$ret = $fiber->start();
49+
$this->assertEquals(2, $ret);
50+
51+
$queue->enqueue($this->expectCallableOnce());
52+
}
53+
3354
/**
3455
* @test
3556
*/

tests/PromiseTest/PromiseFulfilledTestTrait.php

+27
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,33 @@ public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackThrows()
184184
);
185185
}
186186

187+
/**
188+
* @test
189+
* @requires PHP 8.1
190+
*/
191+
public function thenShouldContinueToExecuteCallbacksWhenPriorCallbackSuspendsFiber()
192+
{
193+
$adapter = $this->getPromiseTestAdapter();
194+
$adapter->resolve(42);
195+
196+
$fiber = new \Fiber(function () use ($adapter) {
197+
$adapter->promise()->then(function (int $value) {
198+
\Fiber::suspend($value);
199+
});
200+
});
201+
202+
$ret = $fiber->start();
203+
$this->assertEquals(42, $ret);
204+
205+
$mock = $this->createCallableMock();
206+
$mock
207+
->expects($this->once())
208+
->method('__invoke')
209+
->with($this->identicalTo(42));
210+
211+
$adapter->promise()->then($mock);
212+
}
213+
187214
/** @test */
188215
public function cancelShouldReturnNullForFulfilledPromise()
189216
{

0 commit comments

Comments
 (0)