Skip to content

Commit d558de1

Browse files
authored
Merge pull request #6348 from WoltLab/6.2-unique-key-background_job
Unique key for `wcf1_background_job.identifier`
2 parents 2721ddc + 4151fb6 commit d558de1

File tree

5 files changed

+34
-39
lines changed

5 files changed

+34
-39
lines changed

com.woltlab.wcf/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252

5353
<!--
5454
Required order of the following steps for the update to 6.2:
55+
<instruction type="script">acp/update_com.woltlab.wcf_6.2_backgroundJob.php</instruction>
5556
<instruction type="database" run="standalone">acp/database/update_com.woltlab.wcf_62_step1.php</instruction>
5657
<instruction type="script">acp/update_com.woltlab.wcf_6.2_contactOptions.php</instruction>
5758
<instruction type="database" run="standalone">acp/database/update_com.woltlab.wcf_62_step2.php</instruction>

wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.2_step1.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@
1010

1111
use wcf\system\database\table\column\IntDatabaseTableColumn;
1212
use wcf\system\database\table\column\MediumtextDatabaseTableColumn;
13-
use wcf\system\database\table\column\TextDatabaseTableColumn;
14-
use wcf\system\database\table\column\TinyintDatabaseTableColumn;
1513
use wcf\system\database\table\index\DatabaseTableForeignKey;
14+
use wcf\system\database\table\index\DatabaseTableIndex;
1615
use wcf\system\database\table\PartialDatabaseTable;
1716

1817
return [
18+
PartialDatabaseTable::create('wcf1_background_job')
19+
->indices([
20+
DatabaseTableIndex::create('identifier')
21+
->type(DatabaseTableIndex::UNIQUE_TYPE)
22+
->columns(['identifier']),
23+
]),
1924
PartialDatabaseTable::create('wcf1_user')
2025
->columns([
2126
IntDatabaseTableColumn::create('avatarFileID')
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/**
4+
* This script removes duplicate background jobs.
5+
*/
6+
7+
use wcf\system\WCF;
8+
9+
$sql = "DELETE background_jobs
10+
FROM wcf1_background_job background_jobs
11+
JOIN (
12+
SELECT MIN(jobID) as keepID, identifier
13+
FROM wcf1_background_job
14+
WHERE identifier IS NOT NULL
15+
GROUP BY identifier
16+
HAVING COUNT(*) > 1
17+
) AS duplicates
18+
ON background_jobs.identifier = duplicates.identifier
19+
WHERE background_jobs.jobID <> duplicates.keepID";
20+
$statement = WCF::getDB()->prepare($sql);
21+
$statement->execute();

wcfsetup/install/files/lib/system/background/BackgroundQueueHandler.class.php

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use wcf\data\user\User;
66
use wcf\system\background\job\AbstractBackgroundJob;
77
use wcf\system\background\job\AbstractUniqueBackgroundJob;
8-
use wcf\system\database\util\PreparedStatementConditionBuilder;
98
use wcf\system\exception\ParentClassException;
109
use wcf\system\session\SessionHandler;
1110
use wcf\system\SingletonFactory;
@@ -73,48 +72,17 @@ public function enqueueAt(AbstractBackgroundJob|array $jobs, int $time): void
7372
$jobs = [$jobs];
7473
}
7574

76-
$identifiers = [];
7775
foreach ($jobs as $job) {
7876
if (!($job instanceof AbstractBackgroundJob)) {
7977
throw new ParentClassException(\get_class($job), AbstractBackgroundJob::class);
8078
}
81-
82-
if ($job instanceof AbstractUniqueBackgroundJob) {
83-
$identifiers[] = $job->identifier();
84-
}
8579
}
8680

87-
if ($identifiers !== []) {
88-
$conditions = new PreparedStatementConditionBuilder();
89-
$conditions->add("identifier IN (?)", [$identifiers]);
90-
91-
$sql = "SELECT DISTINCT identifier
92-
FROM wcf1_background_job
93-
{$conditions}";
94-
$statement = WCF::getDB()->prepare($sql);
95-
$statement->execute($conditions->getParameters());
96-
$existingJobs = $statement->fetchAll(\PDO::FETCH_COLUMN);
97-
98-
$jobs = \array_filter(
99-
$jobs,
100-
function ($job) use ($existingJobs) {
101-
if ($job instanceof AbstractUniqueBackgroundJob && \in_array($job->identifier(), $existingJobs)) {
102-
return false;
103-
}
104-
105-
return true;
106-
}
107-
);
108-
109-
if ($jobs === []) {
110-
return;
111-
}
112-
}
113-
114-
$sql = "INSERT INTO wcf1_background_job
115-
(job, time, identifier)
116-
VALUES (?, ?, ?)";
81+
$sql = "INSERT IGNORE INTO wcf1_background_job
82+
(job, time, identifier)
83+
VALUES (?, ?, ?)";
11784
$statement = WCF::getDB()->prepare($sql);
85+
11886
foreach ($jobs as $job) {
11987
$identifier = null;
12088
if ($job instanceof AbstractUniqueBackgroundJob) {

wcfsetup/setup/db/install.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ CREATE TABLE wcf1_background_job (
241241
time INT(10) NOT NULL,
242242
identifier VARCHAR(191) NULL,
243243

244-
KEY identifier (identifier),
244+
UNIQUE KEY identifier (identifier),
245245
KEY (status, time)
246246
);
247247

0 commit comments

Comments
 (0)