This is the second article in a series I’m writing about using beanstalkd messaging queue with Tomatocart. If you haven’t already, I recommend you read the first article first.
Now that you understand the basic concept of beanstalkd and install it into your web server. It’s time to show you how to use it with TomatoCart system. Let’s see the beanstalkd flow again:
It’s composed of producer, job and worker. We just need to create these elements within TomatoCart. Firstly, we have to install pheanstalk client library and define namespace, class map within composer.json.
Create composer.json
- Create a composer.json file under the root of your TomatoCart directory.
- Put following content into it:
{ "name": "Tomatocart/v1", "description": "TomatoCart opensource ecommerce system", "keywords": ["ecommerce"] , "license": "GPL", "type": "project", "require": { "pda/pheanstalk": "3.1.0" }, "autoload": { "psr-4": { "Toc\\Jobs\\": "includes/jobs" }, "classmap": ["includes/classes/"] } }
3. Run following command to install:
composer install
Create job for sending order created email
- Create jobs fold under includes > classes fold.
- Create SendEmailJob.php within jobs fold.
- Put following code into SendEmailJob.php:
<?php namespace Toc\Jobs; use toC_Email_Template; class SendEmailJob { public function handle($params = []) { $email_template = toC_Email_Template::getEmailTemplate('new_order_created'); $email_template->setData($params->id); if (SEND_EXTRA_ORDER_EMAILS_TO != '') { $extra_emials = explode(',', SEND_EXTRA_ORDER_EMAILS_TO); if (is_array($extra_emials) && !osc_empty($extra_emials)) { foreach($extra_emials as $email) { $email_template->addRecipient('', trim($email)); } } } $email_template->buildMessage(); $email_template->sendEmail(); } }
Create worker for reserving the job and perform it
- Create worker.php under your tomatocart root directory.
- Put following code into worker.php:
<?php include 'vendor/autoload.php'; include 'includes/application_top.php'; use Pheanstalk\Pheanstalk; $queue = new Pheanstalk('127.0.0.1'); while (true) { $reserved_job = $queue->watch('tomatocart') ->ignore('default') ->reserve(); $job_data = json_decode($reserved_job->getData(), false); $job_name = $job_data->name; $params = $job_data->params; $job_class = sprintf('Toc\Jobs\%s', $job_name); $job = new $job_class; $job->handle($params); $queue->delete($reserved_job); }
As you can see, we just connect to the local beanstalkd server and then reserve the job from tomatocart tube. Once get the job, we just need to new the job and call the handle method of it.
Putting job into beanstalkd tube – tomatocart
- Open includes > classes > order.php with an editor.
- Add following line after <?php tag:
include DIR_FS_CATALOG . 'vendor/autoload.php';
- Replace sendEmail function with following code:
function sendEmail($id) { $queue = new Pheanstalk\Pheanstalk('127.0.0.1'); $job = new stdClass(); $job->name = 'SendEmailJob'; $job->params = ['id' => $id]; $job_data = json_encode($job); $queue->useTube('tomatocart')->put($job_data); }
In sendEmail function, we connect to local beanstalkd server and create a SendEmailJob instance and put it into tomatocart tube. In fact, sendEmail function works as a producer in beanstalkd flow.
Run worker in the background
Now, it is necessary to run the worker in the background. For simplicity, i just run the log in the while(true) block. So, it works as a damon. This is a not better way, we should use a process control system such as supervisor to monitor and control the worker. I will write an article about it in the future.
- Login into your server with ssh.
- Go to your TomatoCart root directory.
- Run following command to start the worker:
php worker.php &
Now, the worker will wait the job to be putted into tube and then reserve the job.
Create a new order in TomatoCart
After sending order created email asynchronously, it is really faster to complete the whole checkout procedure. Fascinating!
Final word
In this article, i will show you how to use beanstalkd with TomatoCart to send the order email asynchronously. In the third article, i will show you web interface to monitor the beanstalkd server and manage the job directly in the UI.