Przyjrzałem się this other question. Szukam sposobu, aby zrobić to, co OP tego pytania również chce, a to jest do continue processing php after sending http response, ale w Symfony2.Symfony uruchamiają kod po wysłaniu odpowiedzi
Zaimplementowałem zdarzenie uruchamiane po każdym zakończeniu jądra. Do tej pory tak dobrze, ale to, czego chcę, to to, żeby wystrzelił po PEWNYCH przerwach, w konkretnych działaniach kontrolera, na przykład po wysłaniu formularza, nie za każdym razem na każde żądanie. Dzieje się tak dlatego, że chcę wykonywać pewne ciężkie zadania w określonym czasie i nie chcę, aby użytkownik końcowy oczekiwał na załadowanie strony.
Każdy pomysł, jak mogę to zrobić?
<?php
namespace MedAppBundle\Event;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\Tag;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use JMS\DiExtraBundle\Annotation\Inject;
/**
* Class MedicListener
* @package MedAppBundle\EventListener
* @Service("medapp_test.listener")
* @Tag(name="kernel.event_subscriber")
*/
class TestListener implements EventSubscriberInterface
{
private $container;
private $logger;
/**
* Constructor.
*
* @param ContainerInterface $container A ContainerInterface instance
* @param LoggerInterface $logger A LoggerInterface instance
* @InjectParams({
* "container" = @Inject("service_container"),
* "logger" = @Inject("logger")
* })
*/
public function __construct(ContainerInterface $container, LoggerInterface $logger = null)
{
$this->container = $container;
$this->logger = $logger;
}
public function onTerminate()
{
$this->logger->notice('fired');
}
public static function getSubscribedEvents()
{
$listeners = array(KernelEvents::TERMINATE => 'onTerminate');
if (class_exists('Symfony\Component\Console\ConsoleEvents')) {
$listeners[ConsoleEvents::TERMINATE] = 'onTerminate';
}
return $listeners;
}
}
Jak dotąd subskrybowanych zdarzenie do kernel.terminate jednego, ale oczywiście ta wystrzeliwuje go na każde żądanie. Zrobiłem to, co podobne do Swiftmailer'a: EmailSenderListener To trochę dziwne, że jądro musi nasłuchiwać za każdym razem, nawet jeśli nie zostanie wyzwolone. Wolałbym, żeby był wyrzucany tylko w razie potrzeby, ale nie wiem, jak to zrobić.
i gdzie mogę wykonać mój ciężkie zadanie? Muszę uruchomić zadanie i uruchomić go nawet po wysłaniu odpowiedzi. Odpowiedź nie może czekać na zakończenie zadania. Czy muszę "robić rzeczy" jak [tutaj] (http://stackoverflow.com/a/15273676/2077972)? Lub czy odpowiedź jest wysyłana po tym, co dzieje się w funkcji onTerminate() domyślnie? –
Zdarzenie zakończenia jest przeznaczone do uruchamiania po wysłaniu odpowiedzi. Więc kiedy wywoływana jest funkcja "onTerminate", odpowiedź powinna już być dostępna dla użytkownika. –
Podobno w praktyce nie zawsze tak jest. Sprawdź moją zredagowaną odpowiedź. –