-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLock.php
More file actions
66 lines (58 loc) · 1.47 KB
/
Lock.php
File metadata and controls
66 lines (58 loc) · 1.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
declare(strict_types=1);
namespace Netlogix\JobQueue\FastRabbit;
class Lock
{
private const ONE_PERCENT_OF_A_SECOND = 100000;
/**
* @var string[]
*/
protected $slots = [];
/**
* @var string|null
*/
protected $slotPath;
/**
* @var resource|null
*/
protected $slotPointer;
public function __construct(int $numberOfWorkers, string $lockFileDirectory)
{
@mkdir($lockFileDirectory, 0777, true);
for ($i = 0; $i < $numberOfWorkers; $i++) {
$this->slots[] = $lockFileDirectory . '/' . sha1(__CLASS__ . $i) . '.lock';
}
}
/**
* @template T
* @param callable(): T $run
* @return T
*/
public function run(callable $run)
{
$this->findSlot();
try {
return $run();
} finally {
@unlink($this->slotPath);
flock($this->slotPointer, LOCK_UN);
fclose($this->slotPointer);
}
}
protected function findSlot(): void
{
do {
foreach ($this->slots as $slot) {
$fp = fopen($slot, 'w+');
if (flock($fp, LOCK_EX | LOCK_NB)) {
$this->slotPath = $slot;
$this->slotPointer = $fp;
fputs($fp, (string)getmypid());
return;
}
fclose($fp);
}
usleep(self::ONE_PERCENT_OF_A_SECOND);
} while (true);
}
}