Есть ли способ сделать наблюдателя событий асинхронным в Magento? Я хотел бы использовать это для запуска нескольких длительных сценариев в фоновом режиме после того, как клиент разместил заказ, но я понимаю, что когда отправляется событие, код для наблюдателя выполняется синхронно / немедленно.
Один из способов сделать это, как упомянуто @ user3438533, — это запланировать задание на случай запуска вашего наблюдателя, которое позже может быть выполнено cron. Это безопасно сделать, потому что запланированные на будущее работы с pending
статус в cron_schedule
не будет очищен.
Так как вы начали делать покупки, давайте использовать это в качестве примера. Вы должны быть в состоянии создать простое расширение для того, чтобы привести это в действие. Обычное событие, используемое для выполнения операций после размещения заказа: sales_order_place_after
, поэтому мы будем использовать это для запуска будущей пользовательской задачи cron.
Шаг 1. Настройте наблюдателя событий в config/frontend/events
:
<sales_order_place_after>
<observers>
<scheduleExampleJob>
<class>My_Example_Model_Observer</class>
<method>scheduleExampleJob</method>
</scheduleExampleJob>
</observers>
</sales_order_place_after>
Шаг 2. Настройте обработчик заданий cron, который будет прослушивать новое настраиваемое задание, созданное в обозревателе в разделе 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;
}
}
Других решений пока нет …