execute() public static method

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.
See also: 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.
return void
コード例 #1
0
ファイル: LoopTest.php プロジェクト: async-interop/event-loop
 /** @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
ファイル: Thread.php プロジェクト: koolkode/async
 /**
  * @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
ファイル: ProcessPool.php プロジェクト: koolkode/async
 /**
  * @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
ファイル: AsyncTestCase.php プロジェクト: koolkode/async
 /**
  * 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
ファイル: ThreadPool.php プロジェクト: koolkode/async
 /**
  * @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
ファイル: Bootstrap.php プロジェクト: koolkode/k1
 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
ファイル: worker.php プロジェクト: koolkode/async
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());