Use action scheduler's unique single action for daemon run

With the new unique parameter added in the action scheduler 3.5.0 the
as_schedule_single_action that schedules an immediate action
seems to be more convenient for the action scheduler.
We get better control over the scheduling of subsequent runs.
Note: We don't want to use the async action that is also executed immediately,
but it has the highest priority and we don't want to block actions scheduled by other plugins.
[MAILPOET-4684]
This commit is contained in:
Rostislav Wolny
2022-09-28 15:25:46 +02:00
committed by Aschepikov
parent e33539c5ca
commit a03f8f1c30
6 changed files with 24 additions and 6 deletions

View File

@@ -2,13 +2,28 @@
namespace MailPoet\Cron\ActionScheduler;
use MailPoet\WP\Functions as WPFunctions;
class ActionScheduler {
public const GROUP_ID = 'mailpoet-cron';
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
public function scheduleRecurringAction(int $timestamp, int $interval_in_seconds, string $hook, array $args = [], bool $unique = true): int {
return as_schedule_recurring_action($timestamp, $interval_in_seconds, $hook, $args, self::GROUP_ID, $unique);
}
public function scheduleImmediateSingleAction(string $hook, array $args = [], bool $unique = true): int {
return as_schedule_single_action($this->wp->currentTime('timestamp', true), $hook, $args, self::GROUP_ID, $unique);
}
public function unscheduleAction(string $hook, array $args = []): ?int {
$id = as_unschedule_action($hook, $args, self::GROUP_ID);
return $id !== null ? intval($id) : null;

View File

@@ -79,12 +79,11 @@ class DaemonRun {
*/
public function afterProcess(): void {
if ($this->wordpressTrigger->checkExecutionRequirements()) {
$this->actionScheduler->scheduleImmediateSingleAction(self::NAME);
// The automatic rescheduling schedules the next recurring action to run after 1 second.
// So we need to wait before we trigger new remote executor to avoid skipping the action
sleep(2);
$this->remoteExecutorHandler->triggerExecutor();
} else {
$this->actionScheduler->unscheduleAction(self::NAME);
}
}

View File

@@ -55,8 +55,8 @@ class DaemonTrigger {
if ($this->actionScheduler->hasScheduledAction(DaemonRun::NAME)) {
return;
}
// Start recurring action with minimal interval to ensure continuous execution of the daemon
$this->actionScheduler->scheduleRecurringAction($this->wp->currentTime('timestamp', true) - 1, 1, DaemonRun::NAME);
// Schedule immediate action for execution of the daemon
$this->actionScheduler->scheduleImmediateSingleAction(DaemonRun::NAME);
$this->remoteExecutorHandler->triggerExecutor();
}
}

View File

@@ -68,6 +68,10 @@ parameters:
message: '/^Function as_schedule_recurring_action invoked with 6 parameters, 3-5 required.$/'
count: 1
path: ../../lib/Cron/ActionScheduler/ActionScheduler.php
- # WooCommerce stubs contains stubs for older ActionScheduler version
message: '/^Function as_schedule_single_action invoked with 5 parameters, 2-4 required.$/'
count: 1
path: ../../lib/Cron/ActionScheduler/ActionScheduler.php
reportUnmatchedIgnoredErrors: true
dynamicConstantNames:
- MAILPOET_PREMIUM_INITIALIZED

View File

@@ -41,7 +41,7 @@ class DaemonRunTest extends \MailPoetTest {
$this->daemonRun->init();
expect($this->daemonRun->getDaemonExecutionLimit())->equals(20); // Verify initial execution limit
$this->actionScheduler->scheduleRecurringAction(time() - 1, 100, DaemonRun::NAME);
$this->actionScheduler->scheduleImmediateSingleAction(DaemonRun::NAME);
$actions = $this->actionSchedulerHelper->getMailPoetScheduledActions();
expect($actions)->count(1);
$doneActions = $this->actionSchedulerHelper->getMailPoetCompleteActions();

View File

@@ -50,7 +50,7 @@ class DaemonActionSchedulerRunnerTest extends \MailPoetTest {
public function testItDeactivatesAllTasksOnTrigger(): void {
$this->actionScheduler->scheduleRecurringAction(time() - 1, 100, DaemonTrigger::NAME);
$this->actionScheduler->scheduleRecurringAction(time() - 1, 100, DaemonRun::NAME);
$this->actionScheduler->scheduleImmediateSingleAction(DaemonRun::NAME);
$actions = $this->actionSchedulerHelper->getMailPoetScheduledActions();
expect($actions)->count(2);
$this->actionSchedulerRunner->init(false);