2014-05-18 11 views
13

Moje zrozumienie kernel.terminate polega na tym, że po wywołuje on odpowiedź na klienta.Odpowiedź zwrócona dopiero po zdarzeniu kernel.terminate

W moich testach trudne, nie wydaje się, aby tak było. Jeśli wstawię sleep(10) w funkcji, która jest wywoływana na kernel.terminate. przeglądarka czeka również przez 10 sekund. Przetwarzanie wydaje się mieć miejsce przed wysłaniem odpowiedzi.

Mam następujący w config:

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

Moja klasa abonent:

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

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

UPDATE

To wydaje się być związane z Symfony nie wysyłając Content-Length nagłówek. Jeśli to wygeneruję, odpowiedź wróci poprawnie.

// 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

Czy to błąd w Symfony, czy jest jakiś cel? –

Odpowiedz

11

Ten numer okazał się bardzo specyficzny dla mojej konfiguracji (Nginx, PHP-FCGI, Symfony).

Było kilka kwestii w sztuce, który spowodował problem:

  1. Symfony nie zawiera Content-Length ani Connection: close nagłówek
  2. PHP-fcgi nie obsługuje fastcgi_finish_request funkcji
  3. Nginx buforują Odpowiedź od PHP-FCGI, ponieważ Gzip jest na

Rozwiązaniem było przejście z PHP-FCGI do PHP-FPM w celu uzyskać wsparcie dla fastcgi_finish_request. Symfony wewnętrznie wywołuje to przed wykonaniem logiki kończącej jądro, definiując w ten sposób definitywne zamknięcie połączenia.

Innym sposobem rozwiązania tego problemu byłoby wyłączenie Gzip na Nginx, ale nie było to dla mnie możliwe.

Powiązane problemy