My understanding of kernel.terminate
is that it triggers after the response has been returned to the client.
In my testing tough, this does not appear to be the case. If I put a sleep(10)
in the function that's called on kernel.terminate. the browser also waits for 10 seconds. The processing seems to be happening before the response is sent.
I have the following in config:
calendar:
class: Acme\CalendarBundle\Service\CalendarService
arguments: [ @odm.document_manager, @logger, @security.context, @event_dispatcher ]
tags:
- { name: kernel.event_subscriber }
My subscriber class:
class CalendarService implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
'kernel.terminate' => 'onKernelTerminate'
);
}
public function onKernelTerminate()
{
sleep(10);
echo "hello";
}
}
UPDATE
This appears to be related to Symfony not sending a Content-Length
header. If I generate that, the response return properly.
// app_dev.php
...
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
// --- START EDITS ---
$size = strlen($response->getContent());
$response->headers->set('Content-Length', $size);
$response->headers->set('Connection', 'close');
// ---- END EDITS ----
$response->send();
$kernel->terminate($request, $response);
This issue turned out to be very specific to my setup (Nginx, PHP-FCGI, Symfony).
There were a handful of issues in play that caused the issue:
Content-Length
norConnection: close
headerfastcgi_finish_request
functionThe solution was to switch from PHP-FCGI to PHP-FPM in order to get support for
fastcgi_finish_request
. Symfony internally calls this before executing the kernel terminate logic thereby definitively closing the connection.Another way to solve this would be to turn off Gzip on Nginx, but this wasn't really an option for me.