2016-07-08 2 views
-2

В моем контроллере после ответа я должен выполнить некоторую работу. Что лучше использовать: 1. Слушайте событие kernel.terminate или 2. Отправляйте мое пользовательское событие ?События Symfony Kernel vs Пользовательские события

Почему kernel.terminate?

Как вы можете видеть, позвонив по телефону $ kernel-> прекратить после отправки ответа, вы будете запускать kernel.terminate событие, где вы можете выполнить определенные действия, которые вы, возможно, с задержкой, чтобы вернуть в ответ как можно быстрее клиенту (например, отправка писем).

Но с другой стороны это нормально проверять каждый запрос у моего подписчика?

+1

Это зависит от того, что вы на самом деле делаете. – Gerry

+0

Gerry, я должен отправить сообщение в очередь Gearman. –

+0

В идеале для меня используется подписка на событие kernel.terminate, но я сомневаюсь, что это хорошо слушать каждый запрос? –

ответ

2

kernel.terminate происходит после того, как ответ посылают, и может быть полезным для некоторых «тяжелых» операций, которые можно выполнять после того, как клиент получил ответ. Однако есть несколько недостатков: главным образом, если что-то пойдет не так, нет способа дать правильную обратную связь пользователю (например, повторить попытку или сообщить о проблеме). Кроме того, не все ошибки могут регистрироваться (см. https://github.com/symfony/symfony/issues/19078).

Поскольку вы хотите публиковать задания в очереди Gearman, я предлагаю избегать использования kernel.terminate, поскольку обычно публикация задания не требует значительных ресурсов и должна быть сделана перед отправкой ответа. Таким образом, вы можете запустить свое пользовательское событие или, возможно, даже полностью избежать диспетчера событий, сделав более явный вызов в вашем контроллере.

2

Вы не сможете провести собственное мероприятие после ответа без использования kernel.terminate. Потому что это единственное действие, которое может иметь значение после ответа. Мы можем подтвердить это, взглянув на фронт-контроллер app.php:

$request = Request::createFromGlobals(); 
$response = $kernel->handle($request); 
$response->send(); 
$kernel->terminate($request, $response); 

Как примечание, kernel.terminate будет работать only if you use PHP-FPM. В противном случае нет решения за пределами использования некоторой очереди сообщений.

Наконец, общий шаблон состоит в том, чтобы динамически добавлять слушателя на kernel.terminate. Изнутри контроллера, при условии, что вам нужно позвонить my_service:

$myService = $this->get('my_service'); 

$this->get('event_dispatcher')->addListener('kernel.terminate', function (Event $event) use (myService) { 
    $myService->doSomething(); 
}); 
+0

Я вижу, это. Это не имеет значения, когда событие отправки, я могу сделать это после сохранения в db. Но когда я использую скрипт kernel.terminate, вы не будете ждать, пока работа над событиями будет выполнена. С другой стороны, как я уже сказал, хорошо слушать каждый запрос –

+0

Вы хотите какое-то синхронное событие, которое вы имеете в виду? Затем вы можете использовать kernel.response. – romaricdrigon

+0

Технически вы можете запустить свое пользовательское событие внутри слушателя kernel.terminate. – Gerry

Смежные вопросы