Skip to content

Commit f7b6791

Browse files
committed
feat: Rescheduling overdue tasks
1 parent 916a6fc commit f7b6791

File tree

3 files changed

+66
-32
lines changed

3 files changed

+66
-32
lines changed

src/Scheduler.php

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -85,35 +85,44 @@ public function scheduleTask(): void
8585
$taskclass = $this->task::class;
8686
$filetasks = "$dir/$taskclass";
8787

88-
$schedule = [
89-
[
90-
"next" => $next,
91-
"status" => self::STATUS_SCHEDULED
92-
]
93-
];
94-
9588
if (!is_file($filetasks)) {
89+
$schedule = [
90+
[
91+
"next" => $next,
92+
"status" => self::STATUS_SCHEDULED
93+
]
94+
];
9695
file_put_contents($filetasks, json_encode($schedule));
9796
return;
9897
}
9998

100-
if (is_file($filetasks)) {
101-
$schedules = json_decode(file_get_contents($filetasks));
102-
$lastIndex = array_key_last($schedules);
103-
$lastScheduled = $schedules[$lastIndex];
99+
$schedules = json_decode(file_get_contents($filetasks));
100+
$lastIndex = array_key_last($schedules);
101+
$lastScheduled = $schedules[$lastIndex];
102+
$now = date("Y-m-d H:i");
104103

105-
if ($lastScheduled->status == self::STATUS_SCHEDULED) {
106-
return;
107-
}
104+
if ($lastScheduled->status == self::STATUS_SCHEDULED && $now < $lastScheduled->next) {
105+
return;
106+
}
108107

109-
if ($lastScheduled->status == self::STATUS_DONE) {
110-
array_push($schedules, [
111-
"next" => $next,
112-
"status" => self::STATUS_SCHEDULED
113-
]);
108+
if ($lastScheduled->status == self::STATUS_SCHEDULED && $now > $lastScheduled->next) {
109+
$schedules[$lastIndex]->status = self::STATUS_RESCHEDULED;
110+
array_push($schedules, [
111+
"next" => $next,
112+
"status" => self::STATUS_SCHEDULED
113+
]);
114+
115+
file_put_contents($filetasks, json_encode($schedules));
116+
return;
117+
}
114118

115-
file_put_contents($filetasks, json_encode($schedules));
116-
}
119+
if ($lastScheduled->status == self::STATUS_DONE) {
120+
array_push($schedules, [
121+
"next" => $next,
122+
"status" => self::STATUS_SCHEDULED
123+
]);
124+
125+
file_put_contents($filetasks, json_encode($schedules));
117126
}
118127
}
119128

@@ -130,18 +139,16 @@ public function runScheduledTask(): void
130139
$include = $_SERVER["CRONJOB_TASKS_DIR"] . "/$taskclass.php";
131140
$schedules = json_decode(file_get_contents($filetask));
132141
$lastIndex = array_key_last($schedules);
142+
$now = date("Y-m-d H:i");
143+
$isRun = $schedules[$lastIndex]->status == self::STATUS_SCHEDULED && $schedules[$lastIndex]->next == $now;
133144

134-
if ($schedules[$lastIndex]->status == self::STATUS_SCHEDULED) {
135-
$now = date("Y-m-d H:i");
136-
if ($schedules[$lastIndex]->next == $now) {
137-
$job = new Job($taskclass, "onTask");
138-
$job->include($include);
139-
$job->execute();
140-
$lastIndex = array_key_last($schedules);
141-
$schedules[$lastIndex]->status = self::STATUS_DONE;
142-
file_put_contents($filetask, json_encode($schedules));
143-
}
144-
145+
if ($isRun) {
146+
$job = new Job($taskclass, "onTask");
147+
$job->include($include);
148+
$job->execute();
149+
$lastIndex = array_key_last($schedules);
150+
$schedules[$lastIndex]->status = self::STATUS_DONE;
151+
file_put_contents($filetask, json_encode($schedules));
145152
}
146153
}
147154
}

src/SchedulerInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface SchedulerInterface
77
{
88
public const string DIR = __DIR__ . "/.scheduler";
99
public const string STATUS_SCHEDULED = "scheduled";
10+
public const string STATUS_RESCHEDULED = "rescheduled";
1011
public const string STATUS_DONE = "done";
1112
public function setTask(TaskInterface $taskInterface): void;
1213
public function getTask(): TaskInterface;

tests/SchedulerTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,30 @@ public function testRescheduleTaskAfterExecutionWithScheduledStatus(): void
9090

9191
$this->assertEquals($schedule->status, SchedulerInterface::STATUS_SCHEDULED);
9292
}
93+
94+
public function testRescheduleOverdueTask(): void
95+
{
96+
$CRONJOB_TASKS_DIR = $_SERVER[self::CRONJOB_TASKS_DIR];
97+
require_once "$CRONJOB_TASKS_DIR/ConsumerTask.php";
98+
99+
$dir = SchedulerInterface::DIR;
100+
$task = new ConsumerTask();
101+
$schedulerMock = new SchedulerMock();
102+
$taskName = $task::class;
103+
$agendas = json_decode(file_get_contents("$dir/$taskName"));
104+
$tomorrow = new DateTime("yesterday");
105+
$agendas[1]->next = date($tomorrow->format("Y-m-d H:i"));
106+
file_put_contents("$dir/$taskName", json_encode($agendas));
107+
108+
$schedulerMock->scheduler->setTask($task);
109+
$schedulerMock->scheduler->getCronParser()->setExpression("* * * * *");
110+
$schedulerMock->scheduler->scheduleTask();
111+
112+
$agendas = json_decode(file_get_contents("$dir/$taskName"));
113+
$reschedule = $agendas[1];
114+
$schedule = $agendas[2];
115+
116+
$this->assertEquals($reschedule->status, SchedulerInterface::STATUS_RESCHEDULED);
117+
$this->assertEquals($schedule->status, SchedulerInterface::STATUS_SCHEDULED);
118+
}
93119
}

0 commit comments

Comments
 (0)