execute() публичный статический Метод

The loop MUST continue to run until it is either stopped explicitly, no referenced watchers exist anymore, or an exception is thrown that cannot be handled. Exceptions that cannot be handled are exceptions thrown from an error handler or exceptions that would be passed to an error handler but none exists to handle them.
См. также: Interop\Async\Loop::setFactory()
public static execute ( callable $callback, Driver $driver = null ) : void
$callback callable The callback to execute.
$driver Interop\Async\Loop\Driver The event loop driver. If `null`, a new one is created from the set factory.
Результат void
Пример #1
0
 /** @test */
 public function executeStackReturnsScopedDriver()
 {
     $driver1 = new DummyDriver();
     $driver2 = new DummyDriver();
     Loop::execute(function () use($driver1, $driver2) {
         $this->assertSame($driver1, Loop::get());
         Loop::execute(function () use($driver2) {
             $this->assertSame($driver2, Loop::get());
         }, $driver2);
         $this->assertSame($driver1, Loop::get());
     }, $driver1);
 }
Пример #2
0
 /**
  * @codeCoverageIgnore
  */
 public function run()
 {
     \ob_start(function () {
     });
     \error_reporting(-1);
     \ini_set('display_errors', false);
     \set_error_handler(function ($severity, $message) {
         if ($severity & \error_reporting()) {
             throw new \Error($message, $severity);
         }
     });
     require_once $this->autoloadFile;
     Loop::execute(function () {
         new Coroutine($this->processWork());
     }, new NativeLoop());
 }
Пример #3
0
 /**
  * @codeCoverageIgnore
  */
 private static function shutdownPool()
 {
     Loop::execute(function () {
         $await = [];
         try {
             foreach (self::$handshakes as list($worker, $defer)) {
                 $defer->fail(new PoolShutdownException('Pool shut down during worker handshake'));
                 $await[] = $worker->dispose();
             }
         } catch (\Throwable $e) {
             fwrite(STDERR, "PROCESS POOL SHUTDOWN ERROR:\n{$e}");
         } finally {
             self::$handshakes = [];
         }
         try {
             foreach (self::$sharedWorkers as $worker) {
                 $await[] = $worker->dispose();
             }
         } catch (\Throwable $e) {
             fwrite(STDERR, "PROCESS POOL SHUTDOWN ERROR:\n{$e}");
         } finally {
             self::$sharedWorkers = null;
         }
         if (self::$serverAwait !== null) {
             try {
                 self::$serverAwait->cancel(new PoolShutdownException('Handshakes done'));
             } catch (\Throwable $e) {
                 fwrite(STDERR, "PROCESS POOL SHUTDOWN ERROR:\n{$e}");
             }
         }
         if (!empty($await)) {
             $await = new AwaitAll($await);
             $await->when(function ($e = null, array $val = null) {
                 if (self::$server !== null) {
                     try {
                         @\fclose(self::$server);
                     } finally {
                         self::$server = null;
                     }
                 }
             });
         }
     }, new NativeLoop());
 }
Пример #4
0
 /**
  * Run test method as a coroutine.
  */
 public final function runTestCaseWithinLoop(...$args)
 {
     $this->setName($this->testMethodNameBackup);
     $result = $this->{$this->testMethodNameBackup}(...$args);
     if ($result instanceof \Generator) {
         $generator = $result;
         $loop = $this->getLoop();
         $e = null;
         try {
             Loop::execute(function () use(&$result, &$e) {
                 $coroutine = new Coroutine($result);
                 $coroutine->when(function ($error, $val = null) use(&$result, &$e) {
                     if ($error) {
                         $e = $error;
                     } else {
                         $result = $val;
                     }
                     $this->disposeTest();
                 });
             }, $loop);
         } finally {
             if ($this->loggers) {
                 try {
                     foreach ($this->loggers as $handler) {
                         $this->getLoopConfig()->getLogger()->removeHandler($handler);
                     }
                 } finally {
                     $this->loggers = [];
                 }
             }
             if ($loop instanceof KoolLoop) {
                 $loop->reset();
             }
         }
         if ($e !== null) {
             throw $e;
         }
         if ($generator->valid()) {
             throw new \RuntimeException('Async test case did not finish!');
         }
     }
     return $result;
 }
Пример #5
0
 /**
  * @codeCoverageIgnore
  */
 private static function shutdownPool()
 {
     Loop::execute(function () {
         $awaitables = [];
         try {
             foreach (self::$sharedWorkers as $worker) {
                 try {
                     $awaitables[] = $worker->dispose();
                 } catch (\Throwable $e) {
                     fwrite(STDERR, "THREAD POOL SHUTDOWN ERROR:\n{$e}");
                 }
             }
         } finally {
             self::$sharedWorkers = null;
         }
         $await = new AwaitAll($awaitables);
         $await->when(function ($e = null, array $threads = null) {
             foreach ((array) $threads as $thread) {
                 $thread->join();
             }
         });
     }, new NativeLoop());
 }
Пример #6
0
 public function run(Container $container, callable $action)
 {
     $logger = LoopConfig::getLogger();
     if ($this->running === 0) {
         foreach ($this->loggers as $handler) {
             $logger->addHandler($handler);
         }
     }
     $this->running++;
     try {
         $buffer = '';
         if ($this->ipc) {
             ob_start(function (string $data, int $phase) use(&$buffer) {
                 $buffer .= $data;
                 return '';
             }, 1, \PHP_OUTPUT_HANDLER_FLUSHABLE);
         }
         Loop::execute(function () use($container, $action, $logger, &$buffer) {
             Loop::setErrorHandler(function (\Throwable $e) use($logger) {
                 $logger->critical('', ['exception' => $e]);
             });
             $watcher = Loop::repeat(500, function () use(&$buffer, $logger) {
                 if ($buffer !== '') {
                     try {
                         $this->ipc->sendOutput($buffer);
                     } finally {
                         $buffer = '';
                     }
                 }
             });
             Loop::unreference($watcher);
             if ($this->contextName === 'development') {
                 $locator = $container->get(ResourceLocator::class);
                 $watcher = Loop::repeat(5000, function () use($locator) {
                     $locator->syncFiles();
                 });
                 Loop::unreference($watcher);
             }
             if ($this->ipc) {
                 $this->ipc->run();
             }
             $signal = function () {
                 if ($this->ipc) {
                     $this->ipc->stop();
                 }
                 Loop::stop();
             };
             // Shutdown on SIGTERM.
             try {
                 Loop::onSignal(15, $signal);
             } catch (UnsupportedFeatureException $e) {
                 // signal handling is not available...
             }
             $action();
         });
     } finally {
         if ($this->ipc) {
             \ob_end_clean();
         }
         $this->running--;
         if ($this->running === 0) {
             foreach ($this->loggers as $handler) {
                 $logger->removeHandler($handler);
             }
         }
     }
 }
Пример #7
0
Loop::execute(function () use(&$exitCode) {
    new Coroutine(function () use(&$exitCode) {
        $id = (string) $_SERVER['id'];
        list($protocol, $peer) = \explode('://', (string) $_SERVER['ipc'], 2);
        $factory = new SocketFactory($peer, $protocol);
        $socket = (yield $factory->createSocketStream(2));
        $transmitter = new SocketTransmitter($socket);
        try {
            yield from $transmitter->send(['id' => $id], SocketTransmitter::TYPE_HANDSHAKE);
            while (true) {
                list($type, $payload) = (yield from $transmitter->receive());
                if ($type === SocketTransmitter::TYPE_EXIT) {
                    yield from $transmitter->send($payload, $type);
                    $socket->close();
                    $exitCode = 0;
                    break;
                }
                try {
                    if (isset($payload['func'])) {
                        if (\substr($payload['func'], 0, 1) === '@') {
                            $result = \substr($payload['func'], 1)(...$payload['args'] ?? []);
                        } else {
                            $result = $payload['func'](...$payload['args'] ?? []);
                        }
                    } elseif (isset($payload['class']) && isset($payload['method'])) {
                        $result = $payload['class']::{$payload['method']}(...$payload['args'] ?? []);
                    } else {
                        throw new \RuntimeException('No callable target passed to threaded worker');
                    }
                } catch (\Throwable $e) {
                    yield from $transmitter->sendError($e);
                    continue;
                }
                yield from $transmitter->send($result, SocketTransmitter::TYPE_DATA);
            }
        } finally {
            Loop::stop();
        }
    });
}, new NativeLoop());