File tree Expand file tree Collapse file tree 2 files changed +53
-1
lines changed
lib/internal/Magento/Framework/Lock Expand file tree Collapse file tree 2 files changed +53
-1
lines changed Original file line number Diff line number Diff line change @@ -37,6 +37,7 @@ class Cache implements \Magento\Framework\Lock\LockManagerInterface
37
37
public function __construct (FrontendInterface $ cache )
38
38
{
39
39
$ this ->cache = $ cache ;
40
+ $ this ->lockSign = $ this ->generateLockSign ();
40
41
}
41
42
42
43
/**
@@ -45,7 +46,7 @@ public function __construct(FrontendInterface $cache)
45
46
public function lock (string $ name , int $ timeout = -1 ): bool
46
47
{
47
48
if (empty ($ this ->lockSign )) {
48
- $ this ->lockSign = \bin2hex ( \random_bytes ( 8 ) );
49
+ $ this ->lockSign = $ this -> generateLockSign ( );
49
50
}
50
51
51
52
$ data = $ this ->cache ->load ($ this ->getIdentifier ($ name ));
@@ -106,4 +107,27 @@ private function getIdentifier(string $cacheIdentifier): string
106
107
{
107
108
return self ::LOCK_PREFIX . $ cacheIdentifier ;
108
109
}
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
+ }
109
133
}
Original file line number Diff line number Diff line change @@ -53,6 +53,16 @@ public function testUnlock(): void
53
53
{
54
54
$ identifier = 'lock_name ' ;
55
55
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
+
56
66
$ this ->frontendCacheMock
57
67
->expects ($ this ->once ())
58
68
->method ('remove ' )
@@ -61,4 +71,22 @@ public function testUnlock(): void
61
71
62
72
$ this ->assertEquals (true , $ this ->cache ->unlock ($ identifier ));
63
73
}
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
+ }
64
92
}
You can’t perform that action at this time.
0 commit comments