Queues
During the building stage of your application, you may come against some processes that take longer than a typical web request. This is where queues come into play.
CodefyPHP uses it own native noSQL database for queues, so no database or service configuration is required.
Creating a Job
You may place your class anywhere within your application that makes the most sense. For this example, the namespace App\Infrastructure\Services
will be used.
<?php
declare(strict_types=1);
namespace App\Infrastructure\Services;
use Codefy\Framework\Factory\FileLoggerFactory;
use Codefy\Framework\Proxy\Codefy;
use Codefy\Framework\Queue\SimpleQueue;
use PHPMailer\PHPMailer\Exception;
use Qubus\Http\ServerRequest;
use function Codefy\Framework\Helpers\resource_path;
class NewEmailSignup extends SimpleQueue
{
public string $name = 'New User Email';
public string $schedule = '* * * * *';
public function __construct(protected ServerRequest $request)
{
}
/**
* @inheritDoc
*/
public function handle(): void
{
$mailer = Codefy::$PHP->mailer;
$body = $this->request->getParsedBody();
try {
$mailer
->withSmtp()
->withFrom(address: 'myapp@gmail.com')
->withTo(address: $body['email'])
->withSubject(subject: 'Signup Confirmation')
->withBody(
data: ['MESSAGE' => 'Hello {name}. Your signup was successful...'],
options: ['template_name' => resource_path(path: 'email.html')]
)
->withHtml(isHtml: true)
->send();
} catch (\Exception $e) {
FileLoggerFactory::getLogger()->error($e->getMessage());
}
}
}
To handle the job, we always extend the SimpleQueue
class and use the handle()
method. This method is called when our job is executed. Also, note the two properties added to our job:
$name
- The name property sets the name of our job.$schedule
- The schedule property sets a cron expression for our job. This is used to determine if/and when the job should run.
Note
Please note that the properties defined in the job class, must have a public
visibility.
Sending Job to Queue
Depending on the type of job you need will depend on where you need to queue it. For our example, we will use a controller. Sending a task to the queue is very simple and comes down to one command:
<?php
declare(strict_types=1);
namespace App\Infrastructure\Http\Controllers;
use App\Infrastructure\Services\NewEmailSignup;
use Codefy\Framework\Codefy;
use Codefy\Framework\Http\BaseController;
//
use function Codefy\Framework\Helpers\command;
use function Codefy\Framework\Helpers\site_url;
use function Codefy\Framework\Helpers\queue;
//
final class HomeController extends BaseController
{
public function create(ServerRequest $request): ResponseInterface
{
$command = new CreateUserCommand(data: [
//
'email' => new EmailAddress(value: $request->get('email')),
//
]);
try {
command(command: $command);
queue(queue: new NewEmailSignup(request: $request))->createItem();
return $this->redirect(url: site_url(path: $this->router->url(name: 'home')));
} catch (Exception $e) {
// Handle exception
}
}
}
Consuming the Queue
Since we sent our sample job to the queue, we need to add it to the schedule:
<?php
protected function schedule(Schedule $schedule): void
{
$schedule->php(script: 'codex queue:run')->everyMinute();
}
We set the schedule to run every minute, so that when the cron expression on our job is due, it will run at the exact moment it should.
Breakdown
So let's break down what's happening in the background. When you use the queue
helper: queue(queue: new NewEmailSignup(request: $request))->createItem()
, the job is added to the queue.
Then, when the schedule runs, the cron expression will be checked to see if the job is due. If the job is due, it will pop off from the queue, and the handle()
method will be called.
If the job was processed successfully, the job will be deleted from the queue. If the job did not process successfully, it will be released
, and the queue will try to process it again based on the cron schedule.
The queue will try to process the job 3
times before it is considered for garbage collection
. If you would like to increase that number, add a public execution
property to your job class with a higher number.