symfony

Utilisation de l’évènement kernel.terminate sous Symfony2

A quoi sert l’évènement kernel.terminate ? Regardons du côté de la documentation :

“To perform some “heavy” action after the response has been streamed to the user”.

Une question que vous vous posez surement si vous n’avez pas eu l’occasion de travailler avec cet évènement : “Quand est-ce que je peux utiliser l’évènement “kernel.terminate” pour effectuer mes traitements ?”. La réponse en image :

2013 07 18 1331 Utilisation de lévènement kernel.terminate sous Symfony2

Concrètement, vous pouvez quasiment tout faire si vous utilisez cet évènement. A une chose près : votre traitement ne doit pas altérer la réponse. Pourquoi ? Parce qu’il est déclenché après que la réponse soit envoyé au client. Il n’y à donc plus moyen d’y rajouter des informations ou d’en altérer son contenu dans le but de l’envoyer au client. (Attention kernel.terminate a été rajouté en Symfony2.1, donc si vous êtes encore en 2.0, vous pouvez oublier).

Alors finalement comment le mettre en place ? Voilà un exemple de la classe GuzzleExceptionListener qui écoute 2 évènements.

Explications :

Le premier évènement écouté est, kernel.exception. Ce dernier, lorsqu’il sera déclenché, appellera la méthode onKernelException de la classe GuzzleExceptionListener introspectera la classe de l’exception et regardera si celle ci provient d’une erreur renvoyée par Guzzle à la suite d’un appel à un WebService.

Si c’est le cas, elle modifiera un attribut nommé $fail et renverra une réponse en json au client.

Une fois cette réponse envoyée, Symfony va [via la méthode $kernel->terminate()]; déclencher l’évènement kernel.terminate. Ce qui tombe plutôt bien car notre classe écoute cet évènement aussi. Si jamais $fail renvoie true, le service StatsManager s’occupera d’incrémenter une valeur en base de données (afin de savoir combien de requêtes ont échouées par jour).

Ici, on est loin de gagner des secondes sur la réponse, en effet, incrémenter une valeur en base de données est loin d’être une opération “lourde”, alors pourquoi passer par kernel.terminate ? Parce qu’on peut, alors pourquoi se priver même pour de la “micro” optim ?

Attention cependant à bien débugger votre code, car vous ne verrez aucun output étant donné que la réponse est déjà envoyée.

A savoir que vous pouvez aussi ajoutez un listener directement depuis le dispatcher de Symfony2. Voilà un example avec l’utilisation d’une closure :

 

 

 

Related posts:

2 thoughts on “Utilisation de l’évènement kernel.terminate sous Symfony2

  1. C’est un peu compliqué:
    on peut écouter que terminate, prendre la response qui est dans l’event, et regarder le status code:

    public function onTerminate(PostResponseEvent $event)
    {
    if (500 > $event->getResponse()->getStatusCode()) {
    return
    }

    // Do your stuff
    }

  2. Tristan BESSOUSSA

    Sauf qu’avec ta méthode, on ne sais pas d’ou provient la 500, et le but de mon exemple était de logger les requêtes Guzzle qui échouaient.

    Du coup avec ta méthode on perd cette flexibilié là vu qu’à chaque 500 de ton application tu vas trigger tes actions.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>