2014-05-18 9 views
13

La mia comprensione di kernel.terminate è che fa scattare dopo la risposta è stata restituita al client.Risposta restituita solo dopo l'evento kernel.terminate

Nel mio test difficile, questo non sembra essere il caso. Se metto un sleep(10) nella funzione chiamata su kernel.terminate. il browser attende anche 10 secondi. L'elaborazione sembra avvenire prima che la risposta venga inviata.

Ho il seguente in config:

calendar: 
    class: Acme\CalendarBundle\Service\CalendarService 
    arguments: [ @odm.document_manager, @logger, @security.context, @event_dispatcher ] 
    tags: 
     - { name: kernel.event_subscriber } 

La mia classe abbonato:

class CalendarService implements EventSubscriberInterface 
{ 
    public static function getSubscribedEvents() 
    { 
     return array(
      'kernel.terminate' => 'onKernelTerminate' 
     ); 
    } 

    public function onKernelTerminate() 
    { 
     sleep(10); 
     echo "hello"; 
    } 
} 

UPDATE

Questo sembra essere correlato a Symfony non l'invio di un colpo di testa Content-Length. Se lo faccio, la risposta ritorna correttamente.

// 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); 
+0

Si tratta di un bug in Symfony o di uno scopo? –

risposta

11

Questo problema si è rivelata molto specifico per la mia configurazione (Nginx, PHP-fcgi, Symfony).

C'era una manciata di questioni in gioco che ha causato il problema:

  1. Symfony non include un'intestazione Content-LengthConnection: close
  2. PHP-fcgi non supporta la fastcgi_finish_request funzione di
  3. Nginx buffer la risposta da PHP-FCGI perché Gzip è su

La soluzione era passare da PHP-FCGI a PHP-FPM in ordine per ottenere supporto per fastcgi_finish_request. Symfony lo chiama internamente prima di eseguire la logica di terminazione del kernel, chiudendo definitivamente la connessione.

Un altro modo per risolvere questo problema è disattivare Gzip su Nginx, ma questa non era un'opzione per me.

Problemi correlati