Skip to content

Commit

Permalink
Use fiber for errors as well
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Dec 7, 2024
1 parent f897d2f commit 41098ec
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions src/EventLoop/Internal/AbstractDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Revolt\EventLoop\Internal;

use Fiber;
use Revolt\EventLoop\CallbackType;
use Revolt\EventLoop\DefaultFiberFactory;
use Revolt\EventLoop\Driver;
Expand Down Expand Up @@ -31,7 +32,7 @@ abstract class AbstractDriver implements Driver
private \Fiber $fiber;

private \Fiber $callbackFiber;
private \Closure $errorCallback;
private \Fiber $errorFiber;

/** @var array<string, DriverCallback> */
private array $callbacks = [];
Expand Down Expand Up @@ -87,7 +88,7 @@ public function __construct(?FiberFactory $fiberFactory = null)

$this->createLoopFiber();
$this->createCallbackFiber();
$this->createErrorCallback();
$this->createErrorFiber();

/** @psalm-suppress InvalidArgument */
$this->interruptCallback = $this->setInterrupt(...);
Expand Down Expand Up @@ -407,10 +408,14 @@ final protected function error(\Closure $closure, \Throwable $exception): void
return;
}

$fiber = $this->fiberFactory->create($this->errorCallback);
if ($this->errorFiber->isTerminated()) {
$this->createErrorFiber();
}

/** @noinspection PhpUnhandledExceptionInspection */
$fiber->start($this->errorHandler, $exception);
if ($this->errorFiber->resume($exception) !== $this->internalSuspensionMarker) {
$this->createErrorFiber();
}
}

/**
Expand Down Expand Up @@ -628,16 +633,20 @@ private function createCallbackFiber(): void
});
}

private function createErrorCallback(): void
private function createErrorFiber(): void
{
$this->errorCallback = function (\Closure $errorHandler, \Throwable $exception): void {
try {
$errorHandler($exception);
} catch (\Throwable $exception) {
$this->interrupt = static fn () => $exception instanceof UncaughtThrowable
? throw $exception
: throw UncaughtThrowable::throwingErrorHandler($errorHandler, $exception);
}
};
$this->errorFiber = new \Fiber(function (): void {
do {
try {
$exception = Fiber::suspend($this->internalSuspensionMarker);
($this->errorHandler)($exception);
} catch (\Throwable $exception) {
$this->interrupt = static fn () => $exception instanceof UncaughtThrowable
? throw $exception
: throw UncaughtThrowable::throwingErrorHandler($this->errorHandler, $exception);
}
} while (true);
});
$this->errorFiber->start();
}
}

0 comments on commit 41098ec

Please sign in to comment.