Skip to content

Commit 2af1cac

Browse files
authored
Merge pull request #37 from netlogix/fix/postgres-reset-stale
2 parents ade7402 + 33b2cbb commit 2af1cac

5 files changed

Lines changed: 52 additions & 46 deletions

File tree

Classes/Command/SchedulerCommandController.php

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -61,49 +61,7 @@ public function resetStaleJobsCommand(
6161
string $groupName,
6262
int $minutes = 10
6363
): void {
64-
$tableName = ScheduledJob::TABLE_NAME;
65-
$platform = $this->connection->getDbal()->getDatabasePlatform();
66-
if ($platform instanceof MySqlPlatform)
67-
{
68-
$sql = <<<MySQL
69-
UPDATE {$tableName}
70-
SET running = 0,
71-
claimed = '',
72-
incarnation = incarnation + 1
73-
WHERE running = 1
74-
AND claimed NOT LIKE 'failed(%)'
75-
AND groupname = :groupName
76-
AND activity < NOW() - INTERVAL :minutes MINUTE
77-
MySQL;
78-
}
79-
else if ($platform instanceof PostgreSqlPlatform || $platform instanceof PostgreSQL94Platform)
80-
{
81-
$sql = <<<PostgreSQL
82-
UPDATE {$tableName}
83-
SET running = FALSE,
84-
claimed = '',
85-
incarnation = incarnation + 1
86-
WHERE running = TRUE
87-
AND claimed NOT LIKE 'failed(%)'
88-
AND groupname = :groupName
89-
AND activity < NOW() - make_interval(mins => :minutes)
90-
PostgreSQL;
91-
} else {
92-
throw new \RuntimeException("unsupported database platform " . $this->connection->getDbal()->getDatabasePlatform()->getName());
93-
}
94-
95-
$freed = $this->connection->executeQuery(
96-
sql: $sql,
97-
params: [
98-
'groupName' => $groupName,
99-
'minutes' => max($minutes, 1),
100-
],
101-
types: [
102-
'groupName' => Types::STRING,
103-
'minutes' => Types::SMALLINT,
104-
],
105-
)->rowCount();
106-
64+
$freed = $this->scheduler->resetStaleJobs($groupName, $minutes);
10765
if ($freed) {
10866
$this->outputLine('Freed ' . $freed . ' stale jobs.');
10967
}

Classes/Domain/AbstractScheduler.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Netlogix\JobQueue\Scheduled\Domain;
66

77
use DateTimeImmutable;
8+
use Doctrine\DBAL\Exception;
89
use Doctrine\DBAL\Exception\RetryableException;
910
use Doctrine\DBAL\Types\Types;
1011
use InvalidArgumentException;
@@ -40,6 +41,7 @@ abstract class AbstractScheduler implements Scheduler
4041
protected const SELECT_QUERY = "";
4142
protected const RELEASE_QUERY = "";
4243
protected const SCHEDULE_QUERY = "";
44+
protected const RESET_STALE_JOBS_QUERY = "";
4345

4446
public function injectConnection(Connection $connection): void
4547
{
@@ -274,6 +276,28 @@ public function activity(ScheduledJob $job): void
274276
);
275277
}
276278

279+
/**
280+
* Reset stale jobs that have not changed for too long.
281+
*
282+
* @param string $groupName Free jobs in this group only
283+
* @param int $minutes Count jobs as stale if their last activity was more than these many minutes ago
284+
* @throws Exception
285+
* @return int Number of freed jobs
286+
*/
287+
public function resetStaleJobs(string $groupName, int $minutes): int {
288+
return $this->dbal->executeQuery(
289+
sql: static::RESET_STALE_JOBS_QUERY,
290+
params: [
291+
'groupName' => $groupName,
292+
'minutes' => max($minutes, 1),
293+
],
294+
types: [
295+
'groupName' => Types::STRING,
296+
'minutes' => Types::SMALLINT,
297+
],
298+
)->rowCount();
299+
}
300+
277301
protected function scheduleJob(ScheduledJob $job): void
278302
{
279303
$this->validateGroupName($job->getGroupName());

Classes/Domain/MySQLScheduler.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,15 @@ class MySQLScheduler extends AbstractScheduler {
110110
END
111111
MySQL;
112112

113-
}
113+
protected const RESET_STALE_JOBS_QUERY = <<<MySQL
114+
UPDATE netlogix_jobqueue_scheduled_job
115+
SET running = 0,
116+
claimed = '',
117+
incarnation = incarnation + 1
118+
WHERE running = 1
119+
AND claimed NOT LIKE 'failed(%)'
120+
AND groupname = :groupName
121+
AND activity < NOW() - INTERVAL :minutes MINUTE
122+
MySQL;
123+
124+
}

Classes/Domain/PostgreSQLScheduler.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,15 @@ class PostgreSQLScheduler extends AbstractScheduler {
7575
END;
7676
PostgreSQL;
7777

78-
}
78+
protected const RESET_STALE_JOBS_QUERY = <<<PostgreSQL
79+
UPDATE netlogix_jobqueue_scheduled_job
80+
SET running = 0,
81+
claimed = '',
82+
incarnation = incarnation + 1
83+
WHERE running = 1
84+
AND claimed NOT LIKE 'failed(%)'
85+
AND groupname = :groupName
86+
AND activity < NOW() - make_interval(mins => :minutes)
87+
PostgreSQL;
88+
89+
}

Classes/Domain/Scheduler.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ public function fail(ScheduledJob $job, string $reason): void;
2222

2323
public function activity(ScheduledJob $job): void;
2424

25-
}
25+
public function resetStaleJobs(string $groupName, int $minutes): int;
26+
27+
}

0 commit comments

Comments
 (0)