0

I am using sales_order_place_after event to send an sms to the user. Now, sometimes I have to make a call again when I can't send an sms and this means it takes a lot of time. The customer all this time is stuck on the place order button. Is there a way to make place order loading independent of its event.

EDIT: I must add that I am sending a validation code in that sms and want user to input it on the success page. It is just that it takes 30 to 40 seconds in worst case scenario. Normally it takes 3 seconds for the process to complete. So even though I want the page load time to remain less, I also want the customer to get an sms within 40 seconds. This would mean my observer gets triggered but doesn't hold place order to itself

2

A great strategy for these occurrences is to delay such tasks to a queue. Queued jobs are handled on a separate process at a later point in time, making them asynchronous.

Aside from your use case, queues come in handy for doing newsletter subscriptions and sending user registration mails after order placement.

A popular library based on Redis is Resque, readily available in Magento through the mage-resque extension: https://github.com/ajbonner/mage-resque

Basically you would take your observer method logic, wrap it in a separate function, and put the call to this function on the queue.

Pseudo-Code before:

class My_Module_Model_Observer
{
    public function onSalesOrderPlaceAfter($observer)
    {
        // all the magic
    }
}

Pseudo-Code after:

class My_Module_Model_Observer
{
    public function onSalesOrderPlaceAfter($observer)
    {
        $resque = Mage::getSingleton('mnsresque/factory')->create();
        $resque->addJob(
            'My_Module_Model_Job_SendSms',
            array('phoneNumber' => $phoneNumber)
        );
    }
}

class My_Module_Model_Job_SendSms
{
    public function perform()
    {
        // all the magic
    }
}

For further information, check the PHP-Resque readme as well: https://github.com/chrisboulton/php-resque/blob/master/README.md

  • is there a way in which I don't have to use external libraries? I want both event and observer processes to take place at the same time – RBS Jul 3 '14 at 23:24
  • Jan I am trying to use this library but I don't understand the installation procedure. On windows how am I supposed to add this library to my local repository? – RBS Jul 4 '14 at 12:14
  • I'm afraid Redis is not officially supported on Windows - see redis.io/download for reference. – Jan Papenbrock Jul 9 '14 at 13:48
  • In addition I'm not sure if Resque is the best option for a near real-time use-case like this. – Jan Papenbrock Jul 9 '14 at 13:49
0

You could create a new order status called something along the lines of 'Pending SMS' (or just use the processing/pending status) and then build a cron which loops through all orders with the specified status and sends the SMS. You'd then mark the order as 'Complete SMS' or similar depending on how your system works.

This would mean the user wouldn't have to deal with the loading issues you're facing. It would mean the SMS would be delayed until the cron ran next. You could increase the frequency of the cron if you're worried about the delay.

  • Actually I want customer to have the sms within 10 seconds of pressing place order button. If he doesn't he can resend the sms from success.phtml.But 10 seconds are too long for page load. Customer will get tired. – RBS Jul 3 '14 at 23:29
0

You'd want to separate the process of sending sms from new order creation because of various reasons (client patience, MySql deadlocks, hanging processes, ...). Add a new attribute/column to order's table: sent_sms, default to 0. Query every X minutes the orders with sent_sms == 0 via cron and created_at > current date - fail_safe_date (want latest orders, not all). Send sms for one order and save order sent_sms=1 in table. You can also use instead a separate table with a foreign key to sales_flat_order if there is more data to keep about the order's sms. To safely/quickly save the order's sent_sms = 1 you can use:

$order->getResource()->saveAttribute($this, "sent_sms");
  • actually I am sending a validation code and I need customers to enter it on the website. I thus want customer to get text as soon as possible without holding up place order event – RBS Jul 3 '14 at 23:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.