It is good practice to keep jobs small and simple. Use jobs for a single task and do not create a single job for multiple tasks. When multiple tasks should be executed, create a chain of small jobs which all are executed after each other. In this chapter we will use example of a chain of jobs. First, a PDF file must be generated and after this the PDF must send via email. The jobs look like this:
namespace MyModule\Job;
use SlmQueue\Job\AbstractJob;
class GeneratePdfJob extends AbstractJob
{
public function execute()
{
// Generate PDF file
}
}
class SendEmailJob extends AbstractJob
{
public function execute()
{
// Send the email
}
}
SlmQueue solves the job chain by making the GeneratePdfJob
responsible to start the SendEmailJob
. The job to
email the file is instantiated within the pdf job. Then, it is pushed into the queue. The queue to inject the new
job into can be automatically injected by SlmQueue. In order to do this, an interface QueueAwareInterface
must
be implemented:
namespace MyModule\Job;
use SlmQueue\Job\AbstractJob;
use SlmQueue\Queue\QueueAwareInterface;
use SlmQueue\Queue\QueueInterface;
class GeneratePdfJob extends AbstractJob implements QueueAwareInterface
{
/**
* {@inheritDoc}
*/
protected $queue;
/**
* {@inheritDoc}
*/
public function getQueue()
{
return $this->queue;
}
/**
* {@inheritDoc}
*/
public function setQueue(QueueInterface $queue)
{
$this->queue = $queue;
}
public function execute()
{
// Generate PDF file
$job = new SendEmailJob;
$this->getQueue()->push($job);
}
}
To avoid repeating the interface methods, a trait is provided to ease writing queue aware jobs.
namespace MyModule\Job;
use SlmQueue\Job\AbstractJob;
use SlmQueue\Queue\QueueAwareInterface;
use SlmQueue\Queue\QueueAwareTrait;
class GeneratePdfJob extends AbstractJob implements QueueAwareInterface
{
use QueueAwareTrait;
public function execute()
{
// Generate PDF file
$job = new SendEmailJob;
$this->getQueue()->push($job);
}
}
In the case jobs have dependencies, the job cannot be instantiated with the new
keyword. The job will have a factory
and the job manager must be used to fetch the job from. In this case, retrieve the job manager from the queue first:
namespace MyModule\Job;
use SlmQueue\Job\AbstractJob;
use SlmQueue\Queue\QueueAwareInterface;
use SlmQueue\Queue\QueueAwareTrait;
use MyModule\Service\PdfGenerator;
use Laminas\Mail\Transport\TransportInterface;
class GeneratePdfJob extends AbstractJob implements QueueAwareInterface
{
use QueueAwareTrait;
protected $generator;
public function __construct(PdfGenerator $generator)
{
$this->generator = $generator;
}
public function execute()
{
// Generate PDF file using $this->generator
$queue = $this->getQueue();
$manager = $queue->getJobPluginManager();
$job = $manager->get('MyModule\Job\PrintHelloWorldJob')
$queue->push($job);
}
}
class SendEmailJob extends AbstractJob
{
protected $transport;
public function __construct(TransportInterface $transport)
{
$this->transport = $transport;
}
public function execute()
{
// Send the email using $this->transport
}
}