diff --git a/lib/Cron/CronWorkerScheduler.php b/lib/Cron/CronWorkerScheduler.php index 8cc6afe700..c4fc93e289 100644 --- a/lib/Cron/CronWorkerScheduler.php +++ b/lib/Cron/CronWorkerScheduler.php @@ -23,6 +23,23 @@ class CronWorkerScheduler { $this->scheduledTaskRepository = $scheduledTaskRepository; } + public function scheduleImmediatelyIfNotRunning($taskType, $priority = ScheduledTaskEntity::PRIORITY_LOW): ScheduledTaskEntity { + $task = $this->scheduledTaskRepository->findScheduledOrRunningTask($taskType); + // Do nothing when task is running + if (($task instanceof ScheduledTaskEntity) && $task->getStatus() === null) { + return $task; + } + $now = Carbon::createFromTimestamp($this->wp->currentTime('timestamp')); + // Reschedule existing scheduled task + if ($task instanceof ScheduledTaskEntity) { + $task->setScheduledAt($now); + $task->setPriority($priority); + $this->scheduledTaskRepository->flush(); + } + // Schedule new task + return $this->schedule($taskType, $now, $priority); + } + public function schedule($taskType, $nextRunDate, $priority = ScheduledTaskEntity::PRIORITY_LOW): ScheduledTaskEntity { $alreadyScheduled = $this->scheduledTaskRepository->findScheduledTask($taskType); if ($alreadyScheduled) { diff --git a/tests/integration/Cron/CronWorkerSchedulerTest.php b/tests/integration/Cron/CronWorkerSchedulerTest.php index 78274ab4c9..a3be489ee2 100644 --- a/tests/integration/Cron/CronWorkerSchedulerTest.php +++ b/tests/integration/Cron/CronWorkerSchedulerTest.php @@ -38,6 +38,43 @@ class CronWorkerSchedulerTest extends \MailPoetTest { expect($this->entityManager->getRepository(ScheduledTaskEntity::class)->findAll())->count(1); } + public function testItDoesntScheduleRunningTaskImmediatelyIfRunning() { + $nextRunDate = Carbon::now()->addWeek(); + $task = $this->cronWorkerScheduler->schedule('test', $nextRunDate); + $task->setStatus(null); + $this->entityManager->flush(); + $immediateTask = $this->cronWorkerScheduler->scheduleImmediatelyIfNotRunning('test'); + $tasks = $this->entityManager->getRepository(ScheduledTaskEntity::class)->findAll(); + expect($immediateTask->getId())->equals($task->getId()); + expect($tasks)->count(1); + expect($tasks[0]->getType())->same('test'); + expect($tasks[0]->getStatus())->null(); + expect($tasks[0]->getScheduledAt())->same($nextRunDate); + } + + public function testItRescheduleScheduledTaskImmediatelyIfNotRunning() { + $nextRunDate = Carbon::now()->addWeek(); + $task = $this->cronWorkerScheduler->schedule('test', $nextRunDate); + $immediateTask = $this->cronWorkerScheduler->scheduleImmediatelyIfNotRunning('test'); + $tasks = $this->entityManager->getRepository(ScheduledTaskEntity::class)->findAll(); + expect($immediateTask->getId())->equals($task->getId()); + expect($tasks)->count(1); + expect($tasks[0]->getType())->same('test'); + expect($tasks[0]->getStatus())->same(ScheduledTask::STATUS_SCHEDULED); + expect($tasks[0]->getScheduledAt())->greaterOrEquals(Carbon::now()->subSecond()); + expect($tasks[0]->getScheduledAt())->lessOrEquals(Carbon::now()->addSecond()); + } + + public function testItScheduleTaskImmediatelyIfNotRunning() { + $this->cronWorkerScheduler->scheduleImmediatelyIfNotRunning('test'); + $tasks = $this->entityManager->getRepository(ScheduledTaskEntity::class)->findAll(); + expect($tasks)->count(1); + expect($tasks[0]->getType())->equals('test'); + expect($tasks[0]->getStatus())->equals(ScheduledTask::STATUS_SCHEDULED); + expect($tasks[0]->getScheduledAt())->greaterOrEquals(Carbon::now()->subSecond()); + expect($tasks[0]->getScheduledAt())->lessOrEquals(Carbon::now()->addSecond()); + } + public function testItReschedulesTask() { $nextRunDate = Carbon::now()->subDay(); $task = $this->cronWorkerScheduler->schedule('test', $nextRunDate);