3v4l.org

run code in 300+ PHP versions simultaneously
<?php class FiberPool { /** @var Fiber[] */ private array $fibers = []; private int $max = 10; private array $results = []; public function __construct( private \Generator $generator, ) { } public function wait(): void { while ($this->fibers || $this->generator->valid()) { // Fill up the pending fibers while (count($this->fibers) < $this->max && $this->generator->valid()) { $this->startNextItem(); } foreach ($this->fibers as $key => $fiber) { // TBD: We could try/catch this and set the exception to the results array. if ($fiber->isSuspended()) { $fiber->resume(); } else if (!$fiber->isStarted()) { $fiber->start(); } if ($fiber->isTerminated()) { $this->results[$key] = $fiber->getReturn(); unset($this->fibers[$key]); $this->startNextItem(); } } // If we're in a fiber loop ourselves then suspend up the chain once per loop. if (Fiber::getCurrent()) { Fiber::suspend(); } } } public function getResults(): array { return $this->results; } private function startNextItem(): void { if ($this->generator->valid()) { $callable = $this->generator->current(); $this->fibers[$this->generator->key()] = new Fiber($callable); $this->generator->next(); } } } $consistentSuspend = function () { static $seed = [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0]; return array_pop($seed); }; $example = new FiberPool((function () use ($consistentSuspend) { $output = array_combine(range('A', 'Z'), range(1,26)); foreach ($output as $key => $item) { echo 'generating ', $item, "\n"; yield $key => function () use ($consistentSuspend, $item) { echo 'starting ', $item, "\n"; while ($consistentSuspend()) { echo 'suspending ', $item, "\n"; Fiber::suspend(); } echo 'returning ', $item, "\n"; return $item; }; } })()); $example->wait(); print_r($example->getResults());

preferences:
29.02 ms | 407 KiB | 5 Q