1
0
mirror of https://github.com/danog/amp.git synced 2024-12-04 02:17:54 +01:00

Drop Loop::run() and Loop::stop()

This is a *huge* shift, but there’s no reason for these to exist in a world with top-level await.
This commit is contained in:
Aaron Piotrowski 2020-09-27 09:38:52 -05:00
parent 0eceb48fad
commit 32c2cd6d64
No known key found for this signature in database
GPG Key ID: ADD1EF783EDE9EEB
2 changed files with 4 additions and 88 deletions

View File

@ -3,7 +3,6 @@
namespace Amp; namespace Amp;
use Amp\Loop\Driver; use Amp\Loop\Driver;
use Amp\Loop\DriverControl;
use Amp\Loop\DriverFactory; use Amp\Loop\DriverFactory;
use Amp\Loop\InvalidWatcherError; use Amp\Loop\InvalidWatcherError;
use Amp\Loop\UnsupportedFeatureException; use Amp\Loop\UnsupportedFeatureException;
@ -12,14 +11,12 @@ use Amp\Loop\Watcher;
/** /**
* Accessor to allow global access to the event loop. * Accessor to allow global access to the event loop.
* *
* @see \Amp\Loop\Driver * @see Driver
*/ */
final class Loop final class Loop
{ {
private static Driver $driver; private static Driver $driver;
private static DriverControl $control;
/** /**
* Disable construction as this is a static class. * Disable construction as this is a static class.
*/ */
@ -37,10 +34,6 @@ final class Loop
*/ */
public static function set(Driver $driver): void public static function set(Driver $driver): void
{ {
if (isset(self::$driver) && self::$driver->isRunning()) {
throw new \Error("Can't swap the event loop while it is running");
}
try { try {
self::$driver = new class extends Driver { self::$driver = new class extends Driver {
protected function activate(array $watchers): void protected function activate(array $watchers): void
@ -67,51 +60,9 @@ final class Loop
\gc_collect_cycles(); \gc_collect_cycles();
} finally { } finally {
self::$driver = $driver; self::$driver = $driver;
self::$control = $driver->createControl();
} }
} }
/**
* Run the event loop and optionally execute a callback within the scope of it.
*
* 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.
*
* @param callable|null $callback The callback to execute.
*
* @return void
*/
public static function run(callable $callback = null): void
{
if ($callback) {
self::$driver->defer($callback);
}
self::$control->run();
}
/**
* Stop the event loop.
*
* When an event loop is stopped, it continues with its current tick and exits the loop afterwards. Multiple calls
* to stop MUST be ignored and MUST NOT raise an exception.
*
* @return void
*/
public static function stop(): void
{
self::$control->stop();
}
/**
* @return bool True if the event loop is running, false if it is stopped.
*/
public static function isRunning(): bool
{
return self::$driver->isRunning();
}
/** /**
* Defer the execution of a callback. * Defer the execution of a callback.
* *

View File

@ -230,6 +230,7 @@ namespace Amp\Promise
use Amp\Success; use Amp\Success;
use Amp\TimeoutException; use Amp\TimeoutException;
use React\Promise\PromiseInterface as ReactPromise; use React\Promise\PromiseInterface as ReactPromise;
use function Amp\await;
use function Amp\call; use function Amp\call;
use function Amp\Internal\createTypeError; use function Amp\Internal\createTypeError;
@ -302,10 +303,7 @@ namespace Amp\Promise
} }
/** /**
* Runs the event loop until the promise is resolved. Should not be called within a running event loop. * @deprecated Use {@see await()} instead.
*
* Use this function only in synchronous contexts to wait for an asynchronous operation. Use coroutines and yield to
* await promise resolution in a fully asynchronous application instead.
* *
* @template TPromise * @template TPromise
* @template T as Promise<TPromise>|ReactPromise * @template T as Promise<TPromise>|ReactPromise
@ -317,44 +315,11 @@ namespace Amp\Promise
* @psalm-param T $promise * @psalm-param T $promise
* @psalm-return (T is Promise ? TPromise : mixed) * @psalm-return (T is Promise ? TPromise : mixed)
* *
* @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface.
* @throws \Error If the event loop stopped without the $promise being resolved.
* @throws \Throwable Promise failure reason. * @throws \Throwable Promise failure reason.
*/ */
function wait(Promise|ReactPromise $promise): mixed function wait(Promise|ReactPromise $promise): mixed
{ {
if (!$promise instanceof Promise) { return await($promise);
$promise = adapt($promise);
}
$resolved = false;
try {
$driver = Loop::get();
$control = $driver->createControl();
$promise->onResolve(static function ($e, $v) use (&$resolved, &$value, &$exception, $control) {
$control->stop();
$resolved = true;
$exception = $e;
$value = $v;
});
$control->run();
} catch (\Throwable $throwable) {
throw new \Error("Loop exceptionally stopped without resolving the promise", 0, $throwable);
}
if (!$resolved) {
throw new \Error("Loop stopped without resolving the promise");
}
if ($exception) {
throw $exception;
}
return $value;
} }
/** /**