schmittjoh / JMSJobQueueBundle

Run and Schedule Symfony Console Commands as Background Jobs
http://jmsyst.com/bundles/JMSJobQueueBundle
335 stars 254 forks source link

Event Listener not working on ending states #118

Open clofab opened 8 years ago

clofab commented 8 years ago

Hello,

I use this bundle to mass process files into database and I would like to use Event Listener to mark a file processing as failed as soon as the associated job state is set to failed as well, but it never happen. There is the code :

services : 
loading.job_status_change:
        class: MyBundle\EventListener\JobStatusChangeListener
        tags:
            - { name: kernel.event_listener, event: jms_job_queue.job_state_change, method: onStateChange }

And the event Listener (which for the moment write in a log file for debug):

class JobStatusChangeListener {

    public function onStateChange(StateChangeEvent $event)
    {
        $adress = "%kernel.root_dir%/../web/files/log.txt";
        $file = fopen($adress, "a+");
        $job = $event->getJob();
        $fileId = implode("|",$job->getArgs());
        fwrite($file, PHP_EOL."Job : ".$job->getId()." - File : ".$fileId." - Status : New : ".$event->getNewState()."/ Old :".$job->getState());
        fclose($file);

    }
}

log.txt

Job : 149 - File : 10 - Status : New : running/ Old :pending
Job : 150 - File : 11 - Status : New : running/ Old :pending
Job : 151 - File : 12 - Status : New : running/ Old :pending
Job : 152 - File : 13 - Status : New : running/ Old :pending
Job : 153 - File : 14 - Status : New : running/ Old :pending
Job : 154 - File : 15 - Status : New : running/ Old :pending
Job : 155 - File : 16 - Status : New : running/ Old :pending
Job : 156 - File : 17 - Status : New : running/ Old :pending
Job : 157 - File : 18 - Status : New : running/ Old :pending

So its seems that onStateChange is never triggered when the job will be closed. Any idea why?

clofab commented 8 years ago

I've managed to sort of fix it by listening a postUpdate Event. But the onStateChange event still seems to not be triggered when the job state change from running state to any ending state (failed, succes or incomplete).

eveyrat commented 8 years ago

I could make it work:

app.listener.job:
    class: App\CoreBundle\Listener\JobListener
    arguments:
        - @doctrine.orm.default_entity_manager
    tags:
        - { name: kernel.event_listener, event: jms_job_queue.job_state_change, method: onStateChange }
<?php
namespace App\CoreBundle\Listener;

use App\CoreBundle\Entity\Queue;
use Doctrine\Common\Persistence\ObjectManager;
use JMS\JobQueueBundle\Event\JobEvent;

class JobListener {

    protected $em;

    /**
     * @param ObjectManager $em
     */
    public function __construct(ObjectManager $em)
    {
        $this->em = $em;
    }

    public function onStateChange(JobEvent $event)
    {
        $job = $event->getJob();

        $queue = $job->findRelatedEntity('App\CoreBundle\Entity\Queue');
        if ($queue instanceof Queue) {
            $queue->setJobState($event->getNewState());

            $this->em->persist($queue);
            $this->em->flush();
        }
    }
}
anacona16 commented 8 years ago

Hi, I have the same problem.

The final event is never triggered.

Here, the first condition return false, $this->dispatcher is null, unless when finish Job, thus the event is not dispatched.

Why is null?

anthony-launay commented 8 years ago

Any ideas to fix this ?

anacona16 commented 8 years ago

I have solved as follows:

In app/AppKernel.php

new JMS\DiExtraBundle\JMSDiExtraBundle($this),
new JMS\AopBundle\JMSAopBundle(),