Use a meta field to store the in-progress flag [MAILPOET-1983]

This commit is contained in:
wxa
2019-04-22 21:23:33 +03:00
committed by M. Shull
parent 02020b8271
commit 6c13bc3104
6 changed files with 63 additions and 37 deletions

View File

@@ -129,6 +129,7 @@ class Migrator {
'created_at timestamp NULL,', // must be NULL, see comment at the top
'updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'deleted_at timestamp NULL,',
'meta longtext,',
'PRIMARY KEY (id),',
'KEY type (type),',
'KEY status (status)',

View File

@@ -29,22 +29,23 @@ class WooCommerceSync extends SimpleWorker {
return $this->woocommerce_helper->isWooCommerceActive();
}
function prepareTask(ScheduledTask $task) {
if (is_null($task->status)) {
$this->taskAlreadyInProgress = true;
return false;
}
return parent::prepareTask($task);
}
function processTaskStrategy(ScheduledTask $task) {
if ($this->taskAlreadyInProgress) {
$meta = $task->getMeta();
if (!empty($meta['in_progress'])) {
// Do not run multiple instances of the task
return false;
}
$task->meta = ['in_progress' => true];
$task->save();
$this->woocommerce_segment->synchronizeCustomers();
return true;
}
function complete(ScheduledTask $task) {
$task->meta = null;
return parent::complete($task);
}
}

View File

@@ -1,6 +1,8 @@
<?php
namespace MailPoet\Models;
use MailPoet\Util\Helpers;
use MailPoet\WP\Functions as WPFunctions;
if (!defined('ABSPATH')) exit;
@@ -12,6 +14,7 @@ if (!defined('ABSPATH')) exit;
* @property string|null $type
* @property int $priority
* @property string|null $scheduled_at
* @property string|array|null $meta
*/
class ScheduledTask extends Model {
public static $_table = MP_SCHEDULED_TASKS_TABLE;
@@ -96,10 +99,26 @@ class ScheduledTask extends Model {
if (!$this->priority) {
$this->priority = self::PRIORITY_MEDIUM;
}
if (!Helpers::isJson($this->meta)) {
$this->set(
'meta',
json_encode($this->meta)
);
}
parent::save();
return $this;
}
function asArray() {
$model = parent::asArray();
$model['meta'] = $this->getMeta();
return $model;
}
function getMeta() {
return (Helpers::isJson($this->meta)) ? json_decode($this->meta, true) : $this->meta;
}
function delete() {
try {
\ORM::get_db()->beginTransaction();

View File

@@ -1,18 +0,0 @@
<?php
namespace MailPoet\Models;
class ScheduledTaskStub extends ScheduledTask {
private $store;
public function __get($name) {
return $this->store[$name];
}
public function __set($name, $value) {
$this->store[$name] = $value;
}
public function save() {
}
}

View File

@@ -1,15 +1,12 @@
<?php
namespace MailPoet\Test\Cron\Workers;
use Codeception\Util\Stub;
use Carbon\Carbon;
use MailPoet\Cron\Workers\WooCommerceSync;
use MailPoet\Models\ScheduledTask;
use MailPoet\Segments\WooCommerce as WooCommerceSegment;
use MailPoet\WooCommerce\Helper as WooCommerceHelper;
require_once('ScheduledTaskStub.php');
use MailPoet\Models\ScheduledTaskStub;
class WooCommerceSyncTest extends \MailPoetTest {
function _before() {
$this->woocommerce_segment = $this->createMock(WooCommerceSegment::class);
@@ -32,18 +29,29 @@ class WooCommerceSyncTest extends \MailPoetTest {
function testItCallsWooCommerceSync() {
$this->woocommerce_segment->expects($this->once())
->method('synchronizeCustomers');
$task = Stub::make(ScheduledTask::class);
$task = $this->createScheduledTask();
expect($this->worker->processTaskStrategy($task))->equals(true);
}
function testItWillNotRunInMultipleInstances() {
$this->woocommerce_segment->expects($this->once())
->method('synchronizeCustomers');
$task = new ScheduledTaskStub;
$task->status = ScheduledTask::STATUS_SCHEDULED;
expect($this->worker->prepareTask($task))->equals(true);
$task = $this->createScheduledTask();
expect($this->worker->processTaskStrategy($task))->equals(true);
expect($this->worker->prepareTask($task))->equals(false);
expect($this->worker->processTaskStrategy($task))->equals(false);
expect($task->getMeta())->notEmpty();
}
private function createScheduledTask() {
$task = ScheduledTask::create();
$task->type = WooCommerceSync::TASK_TYPE;
$task->status = null;
$task->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
$task->save();
return $task;
}
function _after() {
\ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
}
}

View File

@@ -6,6 +6,7 @@ use MailPoet\Models\Newsletter;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\SendingQueue;
use MailPoet\Models\ScheduledTaskSubscriber;
use MailPoet\Util\Helpers;
class ScheduledTaskTest extends \MailPoetTest {
function _before() {
@@ -110,6 +111,20 @@ class ScheduledTaskTest extends \MailPoetTest {
expect($count)->equals(0);
}
function testItJsonEncodesMetaWhenSaving() {
$task = ScheduledTask::create();
$meta = array(
'some' => 'value'
);
$task->meta = $meta;
$task->save();
$task = ScheduledTask::findOne($task->id);
expect(Helpers::isJson($task->meta))->true();
expect(json_decode($task->meta, true))->equals($meta);
}
function _after() {
\ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
\ORM::raw_execute('TRUNCATE ' . ScheduledTaskSubscriber::$_table);