Skip to content

Commit b1bac16

Browse files
committed
add skipLocked config
1 parent 8377361 commit b1bac16

File tree

6 files changed

+73
-4
lines changed

6 files changed

+73
-4
lines changed

docs/configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The configuration settings for `database` handler.
3737

3838
* `dbGroup` - The database group to use. Default value: `default`.
3939
* `getShared` - Weather to use shared instance. Default value: `true`.
40+
* `skipLocked` - Weather to use "skip locked" feature to maintain concurrency calls. Default to `true`.
4041

4142
### $redis
4243

docs/running-queues.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ This way, worker will consume jobs with the `low` priority and then with `high`.
6565

6666
### Running many instances of the same queue
6767

68-
As mentioned above, sometimes we may want to have multiple instances of the same command running at the same time. The queue is safe to use in that scenario with all databases except `SQLite3` since it doesn't guarantee that the job will be selected only by one process.
68+
As mentioned above, sometimes we may want to have multiple instances of the same command running at the same time. The queue is safe to use in that scenario with all databases if you keep the `skipLocked` to `true` in the config file. Only for SQLite3 driver this setting is not relevant.
6969

7070
### Handling long-running process
7171

src/Config/Queue.php

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class Queue extends BaseConfig
4545
public array $database = [
4646
'dbGroup' => 'default',
4747
'getShared' => true,
48+
// use skip locked feature to maintain concurrency calls
49+
// this is not relevant for the SQLite3 database driver
50+
'skipLocked' => true,
4851
];
4952

5053
/**

src/Models/QueueJobModel.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function getFromQueue(string $name, array $priority): ?QueueJob
9090
*/
9191
private function skipLocked(string $sql): string
9292
{
93-
if ($this->db->DBDriver === 'SQLite3') {
93+
if ($this->db->DBDriver === 'SQLite3' || config('Queue')->database['skipLocked'] === false) {
9494
return $sql;
9595
}
9696

tests/Models/QueueJobModelTest.php

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter Queue.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace Tests\Models;
15+
16+
use CodeIgniter\Queue\Models\QueueJobModel;
17+
use CodeIgniter\Test\ReflectionHelper;
18+
use Tests\Support\TestCase;
19+
20+
/**
21+
* @internal
22+
*/
23+
final class QueueJobModelTest extends TestCase
24+
{
25+
use ReflectionHelper;
26+
27+
public function testQueueJobModel(): void
28+
{
29+
$model = model(QueueJobModel::class);
30+
$this->assertInstanceOf(QueueJobModel::class, $model);
31+
}
32+
33+
public function testSkipLocked(): void
34+
{
35+
$model = model(QueueJobModel::class);
36+
$method = $this->getPrivateMethodInvoker($model, 'skipLocked');
37+
38+
$sql = 'SELECT * FROM queue_jobs WHERE queue = "test" AND status = 0 AND available_at < 123456 LIMIT 1';
39+
$result = $method($sql);
40+
41+
if ($model->db->DBDriver === 'SQLite3') {
42+
$this->assertSame($sql, $result);
43+
} elseif ($model->db->DBDriver === 'SQLSRV') {
44+
$expected = 'SELECT * FROM queue_jobs WITH (ROWLOCK,UPDLOCK,READPAST) WHERE queue = "test" AND status = 0 AND available_at < 123456 LIMIT 1';
45+
$this->assertSame($expected, $result);
46+
} else {
47+
$expected = 'SELECT * FROM queue_jobs WHERE queue = "test" AND status = 0 AND available_at < 123456 LIMIT 1 FOR UPDATE SKIP LOCKED';
48+
$this->assertSame($expected, $result);
49+
}
50+
}
51+
52+
public function testSkipLockedFalse(): void
53+
{
54+
config('Queue')->database['skipLocked'] = false;
55+
56+
$model = model(QueueJobModel::class);
57+
$method = $this->getPrivateMethodInvoker($model, 'skipLocked');
58+
59+
$sql = 'SELECT * FROM queue_jobs WHERE queue = "test" AND status = 0 AND available_at < 123456 LIMIT 1';
60+
$result = $method($sql);
61+
62+
$this->assertSame($sql, $result);
63+
}
64+
}

tests/_support/Config/Queue.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ class Queue extends BaseQueue
4040
* Database handler config.
4141
*/
4242
public array $database = [
43-
'dbGroup' => 'default',
44-
'getShared' => true,
43+
'dbGroup' => 'default',
44+
'getShared' => true,
45+
'skipLocked' => true,
4546
];
4647

4748
/**

0 commit comments

Comments
 (0)