public function resume($params = null) { $this->generator->send($params); if (!$this->generator->valid()) { $this->closed = true; } return $this->generator->current(); }
/** * @param \Generator $generator */ public function __construct(\Generator $generator) { $this->generator = $generator; /** * @param \Throwable|null $exception Exception to be thrown into the generator. * @param mixed $value Value to be sent into the generator. */ $this->when = function ($exception, $value) { if ($this->depth > self::MAX_CONTINUATION_DEPTH) { // Defer continuation to avoid blowing up call stack. Loop::defer(function () use($exception, $value) { ($this->when)($exception, $value); }); return; } try { if ($exception) { // Throw exception at current execution point. $yielded = $this->generator->throw($exception); } else { // Send the new value and execute to next yield statement. $yielded = $this->generator->send($value); } if ($yielded instanceof Promise) { ++$this->depth; $yielded->when($this->when); --$this->depth; return; } if ($this->generator->valid()) { $got = \is_object($yielded) ? \get_class($yielded) : \gettype($yielded); throw new InvalidYieldError($this->generator, \sprintf("Unexpected yield (%s expected, got %s)", Promise::class, $got)); } $this->resolve($this->generator->getReturn()); } catch (\Throwable $exception) { $this->dispose($exception); } }; try { $yielded = $this->generator->current(); if ($yielded instanceof Promise) { ++$this->depth; $yielded->when($this->when); --$this->depth; return; } if ($this->generator->valid()) { $got = \is_object($yielded) ? \get_class($yielded) : \gettype($yielded); throw new InvalidYieldError($this->generator, \sprintf("Unexpected yield (%s expected, got %s)", Promise::class, $got)); } $this->resolve($this->generator->getReturn()); } catch (\Throwable $exception) { $this->dispose($exception); } }
/** * {@inheritdoc} */ public function tick() { if ($this->firstTick) { $this->firstTick = false; $this->deferred->notify(new MessageEvent($this, $this->generator->current())); } else { $this->deferred->notify(new MessageEvent($this, $this->generator->send(null))); } if (!$this->generator->valid()) { $this->deferred->resolve(new Event($this)); } }
/** * executes the current middleware * * @param ServerRequestInterface $request * @param ResponseInterface $response * @return ResponseInterface */ private function call(ServerRequestInterface $request, ResponseInterface $response) { if ($this->atStart) { $middleware = $this->generator->current(); $this->atStart = false; } else { $middleware = $this->generator->send(null); } if (!$middleware) { return $response; } $callable = $this->app->getMiddlewareCallable($middleware); return call_user_func($callable, $request, $response, $this->next); }
/** * @param \Generator $generator */ public function __construct(Generator $generator) { parent::__construct(); $this->generator = $generator; /** * @param mixed $value The value to send to the generator. */ $this->send = function ($value = null) { if ($this->paused) { // If paused, save callable and value for resuming. $this->next = [$this->send, $value]; return; } try { // Send the new value and execute to next yield statement. $this->next($this->generator->send($value)); } catch (Throwable $exception) { $this->reject($exception); $this->close(); } }; /** * @param \Exception $exception Exception to be thrown into the generator. */ $this->capture = function (Throwable $exception) { if ($this->paused) { // If paused, save callable and exception for resuming. $this->next = [$this->capture, $exception]; return; } try { // Throw exception at current execution point. $this->next($this->generator->throw($exception)); } catch (Throwable $exception) { $this->reject($exception); $this->close(); } }; try { $this->next($this->generator->current()); } catch (Throwable $exception) { $this->reject($exception); $this->close(); } }
/** * @param \Generator $generator */ public function __construct(Generator $generator) { parent::__construct(); $this->generator = $generator; /** * @param mixed $value The value to send to the generator. */ $this->send = function ($value = null) { if ($this->busy) { Loop\queue($this->send, $value); // Queue continuation to avoid blowing up call stack. return; } try { // Send the new value and execute to next yield statement. $this->next($this->generator->send($value)); } catch (Throwable $exception) { $this->reject($exception); } }; /** * @param \Throwable $exception Exception to be thrown into the generator. */ $this->capture = function (Throwable $exception) { if ($this->busy) { Loop\queue($this->capture, $exception); // Queue continuation to avoid blowing up call stack. return; } try { // Throw exception at current execution point. $this->next($this->generator->throw($exception)); } catch (Throwable $exception) { $this->reject($exception); } }; try { $this->next($this->generator->current()); } catch (Throwable $exception) { $this->reject($exception); } }
/** * Send value into generator. * @param mixed $value * @NOTE: This method returns nothing, * while original generator returns something. */ public function send($value) { $this->validateValidity(); try { $this->g->send($value); return; } catch (\Throwable $e) { } catch (\Exception $e) { } $this->e = $e; }
/** * @param \Generator $generator */ public function __construct(Generator $generator) { parent::__construct(); $this->generator = $generator; /** * @param mixed $value The value to send to the generator. */ $this->send = function ($value = null) { if (null === $this->generator) { // Coroutine may have been cancelled. return; } try { // Send the new value and execute to next yield statement. $this->next($this->generator->send($value)); } catch (Throwable $exception) { $this->reject($exception); } }; /** * @param \Throwable $exception Exception to be thrown into the generator. */ $this->capture = function (Throwable $exception) { if (null === $this->generator) { // Coroutine may have been cancelled. return; } try { // Throw exception at current execution point. $this->next($this->generator->throw($exception)); } catch (Throwable $exception) { $this->reject($exception); } }; try { $this->next($this->generator->current()); } catch (Throwable $exception) { $this->reject($exception); } }
/** * When you need to return Result from your function, and it also depends on another * functions returning Results, you can make it a generator function and yield * values from dependant functions, this pattern makes code less bloated with * statements like this: * $res = something(); * if ($res instanceof Ok) { * $something = $res->unwrap(); * } else { * return $res; * } * * Instead you can write: * $something = (yield something()); * * @see /example.php * * @param \Generator $resultsGenerator Generator that produces Result instances * @return Result */ public static function reduce(\Generator $resultsGenerator) { /** @var Result $result */ $result = $resultsGenerator->current(); while ($resultsGenerator->valid()) { if ($result instanceof Err) { return $result; } $tmpResult = $resultsGenerator->send($result->unwrap()); if ($resultsGenerator->valid()) { $result = $tmpResult; } } return $result; }
/** * run coroutine * @return mixed */ public function run() { if ($this->first_run) { $this->first_run = false; return $this->coroutine->current(); } if ($this->exception instanceof \Exception) { $retval = $this->coroutine->throw($this->exception); $this->exception = null; return $retval; } $retval = $this->coroutine->send($this->send_value); $this->send_value = null; return $retval; }
/** * Resumes the execution of the generator. * * @param \Generator $generator */ private function resume(\Generator $generator) { if (!$generator->current() instanceof \Generator) { return $generator->send($generator->current()); } if ($generator->current()->valid()) { $this->resume($generator->current()); return; } $generator->send($generator->current()->getReturn()); }
/** @internal */ function __next_coroutine($yielded, \Generator $generator) { return promise_for($yielded)->then(function ($value) use($generator) { $nextYield = $generator->send($value); return $generator->valid() ? __next_coroutine($nextYield, $generator) : $value; }, function ($reason) use($generator) { $nextYield = $generator->throw(exception_for($reason)); // The throw was caught, so keep iterating on the coroutine return __next_coroutine($nextYield, $generator); }); }
/** * @param \Generator $generator */ public function __construct(Generator $generator) { $this->generator = $generator; parent::__construct(function (callable $resolve, callable $reject) { /** * @param mixed $value The value to send to the generator. * @param \Throwable|null $exception Exception object to be thrown into the generator if not null. */ $this->worker = function ($value = null, Throwable $exception = null) use($resolve, $reject) { if ($this->paused) { // If paused, mark coroutine as ready to resume. $this->ready = true; return; } try { if ($this->initial) { // Get result of first yield statement. $this->initial = false; $this->current = $this->generator->current(); } elseif (null !== $exception) { // Throw exception at current execution point. $this->current = $this->generator->throw($exception); } else { // Send the new value and execute to next yield statement. $this->current = $this->generator->send($value); } if (!$this->generator->valid()) { $resolve($this->generator->getReturn()); $this->close(); return; } if ($this->current instanceof Generator) { $this->current = new self($this->current); } if ($this->current instanceof PromiseInterface) { $this->current->done($this->worker, $this->capture); } else { Loop\queue($this->worker, $this->current); } } catch (Throwable $exception) { $reject($exception); $this->close(); } }; /** * @param \Throwable $exception Exception to be thrown into the generator. */ $this->capture = function (Throwable $exception) { if (null !== $this->worker) { // Coroutine may have been closed. ($this->worker)(null, $exception); } }; Loop\queue($this->worker); return function (Throwable $exception) { try { $current = $this->generator->current(); // Get last yielded value. while ($this->generator->valid()) { if ($current instanceof PromiseInterface) { $current->cancel($exception); } $current = $this->generator->throw($exception); } } finally { $this->close(); } }; }); }
private function responseCodec(\Generator $filter, InternalRequest $ireq) : \Generator { while ($filter->valid()) { $cur = $filter->send(yield); if ($cur !== null) { $ireq->responseWriter->send($cur); } } $cur = $filter->getReturn(); if ($cur !== null) { $ireq->responseWriter->send($cur); } $ireq->responseWriter->send(null); }
public function send($value = null) { if (!$this->generator) { $this->rewind(); } return $this->generator->send($value); }
function asyncCaller(Generator $gen) { global $cmd; $r = $gen->current(); if (isset($r)) { switch ($r[0]) { case 'rpc': foreach (glob(__DIR__ . '/rpc/*.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "rpc SERVEICE START ...\n"; //thrift 的rpc远程调用服务 $gen->send('rpc SERVEICE SUCCESS!'); asyncCaller($gen); break; case 'mysqlpool': foreach (glob(__DIR__ . '/mysql/*.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "mysqlpool SERVEICE START ...\n"; //数据库连接池服务 $gen->send('mysqlpool SERVEICE SUCCESS!'); asyncCaller($gen); break; case 'vmstat': foreach (glob(__DIR__ . '/swoole/Vm*.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "vmstat SERVEICE START ...\n"; //硬件监控服务 $gen->send('vmstat SERVEICE SUCCESS!'); asyncCaller($gen); break; case 'swoolelive': foreach (glob(__DIR__ . '/swoole/SwooleLiveServer.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "swoolelive SERVEICE START ...\n"; //网络直播服务 $gen->send('swoolelive SERVEICE SUCCESS!'); asyncCaller($gen); break; case 'task': foreach (glob(__DIR__ . '/swoole/Task*.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "task SERVEICE START ...\n"; //任务服务器服务 $gen->send('task SERVEICE SUCCESS!'); asyncCaller($gen); break; case 'distributed': foreach (glob(__DIR__ . '/distributed/*.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "distributed SERVEICE START ...\n"; //分布式服务器通讯服务 $gen->send('distributed SERVEICE SUCCESS!'); asyncCaller($gen); break; case 'hprose': foreach (glob(__DIR__ . '/hprose/*.php') as $start_file) { exec($cmd . ' ' . $start_file); } echo "hprose SERVEICE START ...\n"; //hprose提供rpc服务 $gen->send('hprose SERVEICE SUCCESS!'); asyncCaller($gen); break; default: $gen->send('no method'); asyncCaller($gen); break; } } }
/** * @param \Generator $generator */ public function __construct(Generator $generator) { $this->generator = $generator; parent::__construct(function (callable $resolve, callable $reject) { $yielded = $this->generator->current(); if (!$this->generator->valid()) { $resolve($this->generator->getReturn()); $this->close(); return; } /** * @param mixed $value The value to send to the generator. */ $this->send = function ($value = null) use($resolve, $reject) { if ($this->paused) { // If paused, save callable and value for resuming. $this->next = [$this->send, $value]; return; } try { // Send the new value and execute to next yield statement. $yielded = $this->generator->send($value); if (!$this->generator->valid()) { $resolve($this->generator->getReturn()); $this->close(); return; } $this->next($yielded); } catch (Throwable $exception) { $reject($exception); $this->close(); } }; /** * @param \Throwable $exception Exception to be thrown into the generator. */ $this->capture = function (Throwable $exception) use($resolve, $reject) { if ($this->paused) { // If paused, save callable and exception for resuming. $this->next = [$this->capture, $exception]; return; } try { // Throw exception at current execution point. $yielded = $this->generator->throw($exception); if (!$this->generator->valid()) { $resolve($this->generator->getReturn()); $this->close(); return; } $this->next($yielded); } catch (Throwable $exception) { $reject($exception); $this->close(); } }; $this->next($yielded); return function (Throwable $exception) { try { $current = $this->generator->current(); // Get last yielded value. if ($current instanceof PromiseInterface) { $current->cancel($exception); } } finally { $this->close(); } }; }); }
private function responseCodec(\Generator $filter, InternalRequest $ireq) : \Generator { while (($yield = yield) !== null) { $cur = $filter->send($yield); if ($yield === false) { if ($cur !== null) { $ireq->responseWriter->send($cur); if (\is_array($cur)) { // in case of headers, to flush a maybe started body too, we need to send false twice $cur = $filter->send(false); if ($cur !== null) { $ireq->responseWriter->send($cur); } } } $ireq->responseWriter->send(false); } elseif ($cur !== null) { $ireq->responseWriter->send($cur); } } $cur = $filter->send(null); if (\is_array($cur)) { $ireq->responseWriter->send($cur); $filter->send(null); } \assert($filter->valid() === false); $cur = $filter->getReturn(); if ($cur !== null) { $ireq->responseWriter->send($cur); } $ireq->responseWriter->send(null); }