/** * {@inheritdoc} */ public function invokeStaticMethod(string $class, string $method, ...$args) : Awaitable { return $this->executor->execute(function () use($class, $method, $args) { if ($this->available->isEmpty()) { $worker = (yield $this->spawnWorker()); $this->workers->attach($worker); } else { $worker = $this->available->dequeue(); } try { return (yield $worker->executeStaticMethod($class, $method, $args)); } finally { if ($this->workers->contains($worker)) { $this->available->enqueue($worker); } } }); }
/** * Stream a binary WebSocket message. * * @param ReadableStream $stream * @param int $priority * @return int Number of transmitted bytes. * * @throws \InvalidArgumentException When the text is not UTF-8 encoded. */ public function sendBinary(ReadableStream $stream, int $priority = 0) : Awaitable { return $this->writer->execute(function () use($stream) { $type = Frame::BINARY; $len = 0; try { $chunk = (yield $stream->readBuffer(4092)); while (null !== ($next = (yield $stream->readBuffer(4092)))) { $len += (yield $this->writeFrame(new Frame($type, $chunk, false))); $chunk = $next; $type = Frame::CONTINUATION; } if ($chunk !== null) { $len += (yield $this->writeFrame(new Frame($type, $chunk))); } return $len; } finally { $stream->close(); } }, $priority); }
protected function wireMapper(callable $map, Channel $input, int $concurrency = 1) : Channel { $output = new Channel($concurrency * 2); $executor = new Executor($concurrency); $closed = false; $count = 0; $n = 0; $job = null; $job = function () use(&$job, &$count, &$n, &$closed, $executor, $map, $input, $output) { try { if ($this->eof === ($val = (yield $input->receive($this->eof)))) { if (--$count < 1) { $output->close(); } return; } $val = $map($val, $n++); if ($val instanceof \Generator) { $val = (yield from $val); } if (!$closed) { (yield $output->send($val)); $executor->execute($job); } } catch (\Throwable $e) { if (!$closed) { $closed = true; $output->close($e); } } }; for ($i = 0; $i < $concurrency; $i++) { $count++; $executor->execute($job); } return $output; }