Is there any way to make an event observer asynchronous in Magento? I would like to use this to run a few time consuming scripts in the background after a customer has placed an order, but my understanding is that when an event gets dispatched, the code for the observer gets executed synchronously/immediately.
To make writing asynchronous code easier, Magento provides the DeferredInterface to use with asynchronous operations. This allows client code to work with asynchronous operations just as it would with standard operations.
Magento 2 Observers To create an observer in Magento 2, you must place your class file under the ModuleRoot/Observer directory. The observer class file should use Magento\Framework\Event\Observer and Magento\Framework\Event\ObserverInterface class and define the executive function.
Because Magento creates at least three objects in response to the trigger event, observers are slower than plugins; observers provide less flexibility when introducing platform-wide functionality, and event observers have key limits in that they MUST NOT modify the objects they impact.
One way you could accomplish this, as @user3438533 mentioned, is to schedule a job when your observer fires which can get executed later by cron. It is safe to do this because jobs scheduled out in the future with pending
status in cron_schedule
will not get purged.
Since you brought up purchasing, let’s use that as an example. You will need to be able to create a simple extension in order to put this into action. A common event used to do things after an order has been placed is sales_order_place_after
, so we will use that to trigger the future custom cron job.
Step 1. Set up the event observer under config/frontend/events
:
<sales_order_place_after>
<observers>
<scheduleExampleJob>
<class>My_Example_Model_Observer</class>
<method>scheduleExampleJob</method>
</scheduleExampleJob>
</observers>
</sales_order_place_after>
Step 2. Set up the cron job handler that will listen for the new custom job created in the observer under config/crontab/jobs
:
<my_example_job>
<!-- @see My_Example_Model_Observer::scheduleExampleJob -->
<run><model>My_Example_Model_Observer::runExampleJob</model></run>
</my_example_job>
class My_Example_Model_Observer
{
/**
* Triggers my_example_job to get scheduled when it gets fired.
* @param Varien_Event_Observer $observer
* @return $this
*/
public function scheduleExampleJob(Varien_Event_Observer $observer)
{
// Calculate your needed datestamp to schedule the future job.
$scheduleAt = Mage::getModel('core/date')->timestamp('Y-m-d H:i:s', strtotime('30 minutes from now'));
Mage::getModel('cron/schedule')
->setJobCode('my_example_job') // Needs to match config/crontab/jobs node
->setStatus(Mage_Cron_Model_Schedule::STATUS_PENDING)
->setScheduledAt($scheduleAt)
->save();
}
/**
* Handler for my_example_job, executed from crontab.
* @param $schedule
* @return $this
*/
public function runExampleJob($schedule)
{
// Do your asynchronous work!
return $this;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With