1
0
mirror of https://github.com/danog/amp.git synced 2024-12-03 09:57:51 +01:00

Update for FiberScheduler changes

This commit is contained in:
Aaron Piotrowski 2021-01-03 21:30:43 -06:00
parent ae93b4cf21
commit f02dbc8585
No known key found for this signature in database
GPG Key ID: ADD1EF783EDE9EEB
10 changed files with 78 additions and 27 deletions

View File

@ -136,7 +136,7 @@ final class EmitSource
// No value has been emitted, suspend fiber to await next value.
$this->waiting[$position] = \Fiber::this();
return \Fiber::suspend(Loop::getDriver());
return \Fiber::suspend(Loop::getScheduler());
}
public function pipe(): Pipeline
@ -302,7 +302,7 @@ final class EmitSource
if ($pair === null) {
$this->yielding[$position] = \Fiber::this();
return \Fiber::suspend(Loop::getDriver());
return \Fiber::suspend(Loop::getScheduler());
}
[$exception, $value] = $pair;

View File

@ -388,6 +388,16 @@ final class Loop
{
return self::$driver;
}
/**
* Retrieve the active {@see FiberScheduler} instance associated with the event loop driver.
*
* @return \FiberScheduler
*/
public static function getScheduler(): \FiberScheduler
{
return self::$driver->getScheduler();
}
}
// Default factory, don't move this to a file loaded by the composer "files" autoload mechanism, otherwise custom

View File

@ -2,8 +2,15 @@
namespace Amp\Loop;
interface Driver extends \FiberScheduler
interface Driver
{
/**
* Get the fiber scheduler associated with this driver.
*
* @return \FiberScheduler
*/
public function getScheduler(): \FiberScheduler;
/**
* Run the event loop.
*
@ -18,6 +25,8 @@ interface Driver extends \FiberScheduler
* error handler or exceptions that would be passed to an error handler but none exists to handle them.
*
* @return void
*
* @throw \Error Thrown if the event loop is already running.
*/
public function run(): void;

View File

@ -41,6 +41,22 @@ abstract class DriverFoundation implements Driver
private bool $running = false;
private \FiberScheduler $scheduler;
/**
* Get the fiber scheduler associated with this driver.
*
* @return \FiberScheduler
*/
public function getScheduler(): \FiberScheduler
{
if (!isset($this->scheduler) || $this->scheduler->isTerminated()) {
$this->scheduler = new \FiberScheduler(fn() => $this->run());
}
return $this->scheduler;
}
/**
* Run the event loop.
*
@ -55,6 +71,8 @@ abstract class DriverFoundation implements Driver
* error handler or exceptions that would be passed to an error handler but none exists to handle them.
*
* @return void
*
* @throw \Error Thrown if the event loop is already running.
*/
public function run(): void
{

View File

@ -25,6 +25,11 @@ final class TracingDriver implements Driver
$this->driver = $driver;
}
public function getScheduler(): \FiberScheduler
{
return $this->driver->getScheduler();
}
public function run(): void
{
$this->driver->run();

View File

@ -34,7 +34,7 @@ namespace Amp
}
);
return \Fiber::suspend(Loop::getDriver());
return \Fiber::suspend(Loop::getScheduler());
}
/**
@ -226,7 +226,7 @@ namespace Amp
{
$fiber = \Fiber::this();
Loop::delay($milliseconds, fn() => $fiber->resume());
\Fiber::suspend(Loop::getDriver());
\Fiber::suspend(Loop::getScheduler());
}
/**
@ -255,7 +255,7 @@ namespace Amp
$watchers[] = Loop::onSignal($signal, $callback);
}
return \Fiber::suspend(Loop::getDriver());
return \Fiber::suspend(Loop::getScheduler());
}
/**

View File

@ -10,7 +10,7 @@ final class Fiber
/**
* Starts execution of the fiber. Returns when the fiber suspends or terminates.
*
* Must be called within {@see FiberScheduler::run()}.
* Must be called within a {@see FiberScheduler}.
*
* @param mixed ...$args Arguments passed to fiber function.
*
@ -23,7 +23,7 @@ final class Fiber
* Resumes the fiber, returning the given value from {@see Fiber::suspend()}.
* Returns when the fiber suspends or terminates.
*
* Must be called within {@see FiberScheduler::run()}.
* Must be called within a {@see FiberScheduler}.
*
* @param mixed $value
*
@ -36,7 +36,7 @@ final class Fiber
* Throws the given exception into the fiber from {@see Fiber::suspend()}.
* Returns when the fiber suspends or terminates.
*
* Must be called within {@see FiberScheduler::run()}.
* Must be called within a {@see FiberScheduler}.
*
* @param Throwable $exception
*
@ -68,19 +68,19 @@ final class Fiber
/**
* Returns the currently executing Fiber instance.
*
* Cannot be called within {@see FiberScheduler::run()}.
* Cannot be called within {@see FiberScheduler}.
*
* @return self The currently executing fiber.
*
* @throws FiberError Thrown if within {@see FiberScheduler::run()}.
* @throws FiberError Thrown if within {@see FiberScheduler}.
*/
public static function this(): self { }
/**
* Suspend execution of the fiber. The fiber may be resumed with {@see Fiber::resume()} or {@see Fiber::throw()}
* within the run() method of the instance of {@see FiberScheduler} given.
* within the callback used to create the {@see FiberScheduler} given.
*
* Cannot be called within {@see FiberScheduler::run()}.
* Cannot be called within a {@see FiberScheduler}.
*
* @param FiberScheduler $scheduler
*

View File

@ -1,9 +1,29 @@
<?php
interface FiberScheduler
final class FiberScheduler
{
/**
* Run the scheduler.
* @param callable $callback Function to invoke when starting the fiber scheduler.
*/
public function run(): void;
public function __construct(callable $callback) { }
/**
* @return bool True if the fiber has been started.
*/
public function isStarted(): bool { }
/**
* @return bool True if the fiber is suspended.
*/
public function isSuspended(): bool { }
/**
* @return bool True if the fiber is currently running.
*/
public function isRunning(): bool { }
/**
* @return bool True if the fiber has completed execution.
*/
public function isTerminated(): bool { }
}

View File

@ -6,9 +6,4 @@ class ReflectionFiberScheduler extends ReflectionFiber
* @param FiberScheduler $scheduler
*/
public function __construct(FiberScheduler $scheduler) { }
/**
* @return FiberScheduler The instance used to create the fiber.
*/
public function getScheduler(): FiberScheduler { }
}

View File

@ -28,17 +28,11 @@ abstract class DriverTest extends TestCase
*/
abstract public function getFactory(): callable;
/** @var Driver */
public Driver $loop;
public function setUp(): void
{
$this->loop = ($this->getFactory())();
if (!$this->loop instanceof Driver) {
$this->fail("Factory did not return a loop Driver");
}
\gc_collect_cycles();
}