Skip to content

Commit fc8b3fb

Browse files
committed
Merge branch 'MC-32427' into MC-33363
2 parents cccf9bd + c92998d commit fc8b3fb

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

lib/internal/Magento/Framework/Lock/Backend/Cache.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Cache implements \Magento\Framework\Lock\LockManagerInterface
3737
public function __construct(FrontendInterface $cache)
3838
{
3939
$this->cache = $cache;
40+
$this->lockSign = $this->generateLockSign();
4041
}
4142

4243
/**
@@ -45,7 +46,7 @@ public function __construct(FrontendInterface $cache)
4546
public function lock(string $name, int $timeout = -1): bool
4647
{
4748
if (empty($this->lockSign)) {
48-
$this->lockSign = \bin2hex(\random_bytes(8));
49+
$this->lockSign = $this->generateLockSign();
4950
}
5051

5152
$data = $this->cache->load($this->getIdentifier($name));
@@ -106,4 +107,27 @@ private function getIdentifier(string $cacheIdentifier): string
106107
{
107108
return self::LOCK_PREFIX . $cacheIdentifier;
108109
}
110+
111+
/**
112+
* Function that generates lock sign that helps to avoid removing a lock that was created by another client.
113+
*
114+
* @return string
115+
*/
116+
private function generateLockSign()
117+
{
118+
$sign = implode(
119+
'-',
120+
[
121+
\getmypid(), \crc32(\gethostname())
122+
]
123+
);
124+
125+
try {
126+
$sign .= '-' . \bin2hex(\random_bytes(4));
127+
} catch (\Exception $e) {
128+
$sign .= '-' . \rand(0, 1000);
129+
}
130+
131+
return $sign;
132+
}
109133
}

lib/internal/Magento/Framework/Lock/Test/Unit/Backend/CacheTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ public function testUnlock(): void
5353
{
5454
$identifier = 'lock_name';
5555

56+
$closure = \Closure::bind(function ($cacheInstance) {
57+
return $cacheInstance->lockSign;
58+
}, null, $this->cache);
59+
$lockSign = $closure($this->cache);
60+
61+
$this->frontendCacheMock
62+
->expects($this->once())->method('load')
63+
->with(self::LOCK_PREFIX . $identifier)
64+
->willReturn($lockSign);
65+
5666
$this->frontendCacheMock
5767
->expects($this->once())
5868
->method('remove')
@@ -61,4 +71,22 @@ public function testUnlock(): void
6171

6272
$this->assertEquals(true, $this->cache->unlock($identifier));
6373
}
74+
75+
/**
76+
* Verify that lock will no be released without sign matches.
77+
* Sign generates in Cache class constructor.
78+
*
79+
* @return void
80+
*/
81+
public function testUnlockWithAnotherSign(): void
82+
{
83+
$identifier = 'lock_name';
84+
85+
$this->frontendCacheMock
86+
->expects($this->once())->method('load')
87+
->with(self::LOCK_PREFIX . $identifier)
88+
->willReturn(\uniqid('some_rand-'));
89+
90+
$this->assertEquals(false, $this->cache->unlock($identifier));
91+
}
6492
}

0 commit comments

Comments
 (0)