Skip to content

Commit

Permalink
Merge pull request #12 from longxinH/dispatch
Browse files Browse the repository at this point in the history
修复协程模式下堆栈共用情况
  • Loading branch information
longxinH authored Mar 24, 2022
2 parents 8347b94 + fcaba21 commit 8399013
Showing 1 changed file with 28 additions and 8 deletions.
36 changes: 28 additions & 8 deletions src/RouteDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use Exception;
use FastD\Http\ServerRequest;
use FastD\Middleware\Delegate;
use FastD\Middleware\Dispatcher;
use FastD\Middleware\MiddlewareInterface;
use FastD\Routing\Exceptions\RouteException;
Expand Down Expand Up @@ -119,19 +120,19 @@ public function callMiddleware(Route $route, ServerRequestInterface $request)

foreach ($route->getMiddleware() as $middleware) {
if ($middleware instanceof MiddlewareInterface) {
$this->before($middleware);
$prototypeStack->push($middleware);
} else {
if (is_string($middleware)) {
if (class_exists($middleware)) {
$this->before(new $middleware);
$prototypeStack->push(new $middleware);
} elseif (isset($this->definition[$middleware])) {
$definition = $this->definition[$middleware];
if (is_array($definition)) {
foreach ($definition as $value) {
$this->before(is_string($value) ? new $value : $value);
$prototypeStack->push(is_string($value) ? new $value : $value);
}
} else {
$this->before(is_string($definition) ? new $definition : $definition);
$prototypeStack->push(is_string($definition) ? new $definition : $definition);
}
} else {
throw new \RuntimeException(sprintf('Middleware %s is not defined.', $middleware));
Expand All @@ -143,18 +144,37 @@ public function callMiddleware(Route $route, ServerRequestInterface $request)
}

// wrapper route middleware
$this->before(new RouteMiddleware($route));
$prototypeStack->push(new RouteMiddleware($route));

try {
$response = parent::dispatch($request);
$this->stack = $prototypeStack;
$response = $this->PrototypeDispatch($prototypeStack, $request);
unset($prototypeStack);
} catch (\Throwable $exception) {
$this->stack = $prototypeStack;
unset($prototypeStack);
throw $exception;
}

return $response;
}

private function PrototypeDispatch(\SplStack $stack, $request) {
$response = $this->PrototypeResolve($stack)->process($request);

return $response;
}

private function PrototypeResolve(\SplStack $stack) {
return $stack->isEmpty() ?
new Delegate(
function () {
throw new LogicException('unresolved request: middleware stack exhausted with no result');
}
) :
new Delegate(
function (ServerRequestInterface $request) use ($stack) {
return $stack->shift()->handle($request, $this->PrototypeResolve($stack));
}
);
}

}

0 comments on commit 8399013

Please sign in to comment.