Skip to content
This repository was archived by the owner on Jun 25, 2025. It is now read-only.

Commit 72c0bf8

Browse files
committed
Fixed how promises are resolved with GetRequestPromise
1 parent 77b4b3d commit 72c0bf8

File tree

3 files changed

+99
-39
lines changed

3 files changed

+99
-39
lines changed

AsyncHttpKernel.php

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,13 @@ public function handleAsync(
109109

110110
$request->headers->set('X-Php-Ob-Level', ob_get_level());
111111

112-
return $this->handleAsyncRaw(
113-
$request,
114-
$type
115-
)
116-
->then(
117-
function (Response $response) {
118-
return $response;
119-
}, function (\Exception $e) use ($request, $type, $catch) {
112+
return
113+
$this->handleAsyncRaw(
114+
$request,
115+
$type
116+
)
117+
->then(null,
118+
function (\Exception $e) use ($request, $type, $catch) {
120119
if ($e instanceof RequestExceptionInterface) {
121120
$e = new BadRequestHttpException($e->getMessage(), $e);
122121
}
@@ -128,7 +127,8 @@ function (Response $response) {
128127
}
129128

130129
return $this->handleExceptionPromise($e, $request, $type);
131-
});
130+
}
131+
);
132132
}
133133

134134
/**
@@ -167,40 +167,59 @@ private function handleAsyncRaw(
167167
->asyncDispatch(AsyncKernelEvents::ASYNC_REQUEST, $event)
168168
->then(function (PromiseEvent $event) use ($request, $type) {
169169
if ($event->hasPromise()) {
170-
return $this->filterResponsePromise(
171-
$event->getPromise(),
172-
$request,
173-
$type
174-
);
170+
return $event
171+
->getPromise()
172+
->then(function ($response) use ($request, $type) {
173+
return $response instanceof Response
174+
? $this->filterResponsePromise(
175+
new FulfilledPromise($response),
176+
$request,
177+
$type
178+
)
179+
: $this->callAsyncController($request, $type);
180+
});
175181
}
176182

177-
if (false === $controller = $this->resolver->getController($request)) {
178-
throw new NotFoundHttpException(
179-
sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())
180-
);
181-
}
183+
return $this->callAsyncController($request, $type);
184+
});
185+
}
186+
187+
/**
188+
* Call async controller.
189+
*
190+
* @param Request $request
191+
* @param int $type
192+
*
193+
* @return PromiseInterface
194+
*/
195+
private function callAsyncController(Request $request, int $type): PromiseInterface
196+
{
197+
if (false === $controller = $this->resolver->getController($request)) {
198+
throw new NotFoundHttpException(
199+
sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())
200+
);
201+
}
182202

183-
$event = new FilterControllerEvent($this, $controller, $request, $type);
184-
$this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
185-
$controller = $event->getController();
203+
$event = new FilterControllerEvent($this, $controller, $request, $type);
204+
$this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
205+
$controller = $event->getController();
186206

187-
// controller arguments
188-
$arguments = $this->argumentResolver->getArguments($request, $controller);
207+
// controller arguments
208+
$arguments = $this->argumentResolver->getArguments($request, $controller);
189209

190-
$event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
191-
$this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
192-
$controller = $event->getController();
193-
$arguments = $event->getArguments();
210+
$event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
211+
$this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
212+
$controller = $event->getController();
213+
$arguments = $event->getArguments();
194214

195-
/**
196-
* Call controller.
197-
*
198-
* @var PromiseInterface
199-
*/
200-
$promise = $controller(...$arguments);
215+
/**
216+
* Call controller.
217+
*
218+
* @var PromiseInterface
219+
*/
220+
$promise = $controller(...$arguments);
201221

202-
return $this->filterResponsePromise($promise, $request, $type);
203-
});
222+
return $this->filterResponsePromise($promise, $request, $type);
204223
}
205224

206225
/**
@@ -221,12 +240,12 @@ private function filterResponsePromise(PromiseInterface $promise, Request $reque
221240
return $this
222241
->dispatcher
223242
->asyncDispatch(AsyncKernelEvents::ASYNC_RESPONSE, $event)
224-
->then(function (PromiseEvent $event) use ($request, $type) {
243+
->then(function (PromiseEvent $event) use ($request, $type, $promise) {
225244
$this->finishRequestPromise($request, $type);
226245

227246
return $event->hasPromise()
228247
? $event->getPromise()
229-
: new FulfilledPromise();
248+
: $promise;
230249
});
231250
}
232251

AsyncKernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function handleAsync(
4848

4949
$httpKernel = $this->getHttpKernel();
5050
if (!$httpKernel instanceof AsyncHttpKernel) {
51-
throw new AsyncHttpKernelNeededException();
51+
throw new AsyncHttpKernelNeededException('In order to use this AsyncKernel, you need to have the HttpAsyncKernel installed');
5252
}
5353

5454
return $httpKernel->handleAsync(
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony Async Kernel
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*
9+
* Feel free to edit as you please, and have fun.
10+
*
11+
* @author Marc Morera <[email protected]>
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace Symfony\Component\HttpKernel\CompilerPass;
17+
18+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
19+
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\HttpKernel\AsyncEventDispatcher;
21+
use Symfony\Component\HttpKernel\AsyncHttpKernel;
22+
23+
/**
24+
* Class AsyncHttpKernelCompilerPass.
25+
*/
26+
class AsyncHttpKernelCompilerPass implements CompilerPassInterface
27+
{
28+
/**
29+
* You can modify the container here before it is dumped to PHP code.
30+
*/
31+
public function process(ContainerBuilder $container)
32+
{
33+
$container
34+
->getDefinition('event_dispatcher')
35+
->setClass(AsyncEventDispatcher::class);
36+
37+
$container
38+
->getDefinition('http_kernel')
39+
->setClass(AsyncHttpKernel::class);
40+
}
41+
}

0 commit comments

Comments
 (0)