execute() public static méthode

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.
Résultat void
 /** @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);
 }
Exemple #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());
 }
Exemple #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());
 }
Exemple #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;
 }
Exemple #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());
 }
Exemple #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);
             }
         }
     }
 }
Exemple #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());