Search code examples
symfonysymfony-3.2

How tout use kernel.terminate Event in a Service


I do a service that run an heavy task, this service is call in a Controller. To avoid a too long page loading, I want return the HTTP Response and run the heavy task after.

I've read we can use kernel.terminate event to do it, but I don't understand how to use it.

For the moment I try to do a Listener on KernelEvent:TERMINATE, but I don't know how to filter, for the Listener only execute the job on the good page...

Is it possible to add a function to execute on when the Event is trigger ? Then in my controller I juste use the function to add my action, and Symfony execute it later.

Thanks for your help.


Solution

  • Finally, I've find how to do it, I use the EventDispatcher in my Service and I connecting a Listener here a PHP Closure: http://symfony.com/doc/current/components/event_dispatcher.html#connecting-listeners

    use Symfony\Component\EventDispatcher\Event;
    use Symfony\Component\EventDispatcher\EventDispatcherInterface;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    class MyService
    {
      private $eventDispatcher;
    
      public function __construct(TokenGenerator $tokenGenerator, EventDispatcherInterface $eventDispatcher)
      {
       $this->tokenGenerator = $tokenGenerator;
       $this->eventDispatcher = $eventDispatcher;
      }
    
      public function createJob($query)
     {
        // Create a job token
        $token = $this->tokenGenerator->generateToken();
    
        // Add the job in database
        $job = new Job();
        $job->setName($token);
        $job->setQuery($query);
    
        // Persist the job in database
        $this->em->persist($job);
        $this->em->flush();
    
        // Call an event, to process the job in background
        $this->eventDispatcher->addListener(KernelEvents::TERMINATE, function (Event $event) use ($job) {
            // Launch the job
            $this->launchJob($job);
        });
    
        return $job;
     }