@@ -48,22 +48,31 @@ class LockGuardedCacheLoader
48
48
private $ loadTimeout ;
49
49
50
50
/**
51
- * LockGuardedCacheLoader constructor.
51
+ * Minimal delay timeout in ms.
52
+ *
53
+ * @var int
54
+ */
55
+ private $ minimalDelayTimeout ;
56
+
57
+ /**
52
58
* @param LockManagerInterface $locker
53
59
* @param int $lockTimeout
54
60
* @param int $delayTimeout
55
61
* @param int $loadTimeout
62
+ * @param int $minimalDelayTimeout
56
63
*/
57
64
public function __construct (
58
65
LockManagerInterface $ locker ,
59
66
int $ lockTimeout = 10000 ,
60
67
int $ delayTimeout = 20 ,
61
- int $ loadTimeout = 10000
68
+ int $ loadTimeout = 10000 ,
69
+ int $ minimalDelayTimeout = 5
62
70
) {
63
71
$ this ->locker = $ locker ;
64
72
$ this ->lockTimeout = $ lockTimeout ;
65
73
$ this ->delayTimeout = $ delayTimeout ;
66
74
$ this ->loadTimeout = $ loadTimeout ;
75
+ $ this ->minimalDelayTimeout = $ minimalDelayTimeout ;
67
76
}
68
77
69
78
/**
@@ -100,7 +109,7 @@ public function lockedLoadData(
100
109
}
101
110
102
111
if ($ cachedData === false ) {
103
- usleep ($ this ->delayTimeout * 1000 );
112
+ usleep ($ this ->getLookupTimeout () * 1000 );
104
113
$ cachedData = $ dataLoader ();
105
114
}
106
115
}
@@ -118,7 +127,7 @@ public function lockedLoadData(
118
127
public function lockedCleanData (string $ lockName , callable $ dataCleaner )
119
128
{
120
129
while ($ this ->locker ->isLocked ($ lockName )) {
121
- usleep ($ this ->delayTimeout * 1000 );
130
+ usleep ($ this ->getLookupTimeout () * 1000 );
122
131
}
123
132
try {
124
133
if ($ this ->locker ->lock ($ lockName , $ this ->lockTimeout / 1000 )) {
@@ -128,4 +137,18 @@ public function lockedCleanData(string $lockName, callable $dataCleaner)
128
137
$ this ->locker ->unlock ($ lockName );
129
138
}
130
139
}
140
+
141
+ /**
142
+ * Delay will be applied as rand($minimalDelayTimeout, $delayTimeout).
143
+ * This helps to desynchronize multiple clients trying
144
+ * to acquire the lock for the same resource at the same time
145
+ *
146
+ * @return int
147
+ */
148
+ private function getLookupTimeout ()
149
+ {
150
+ $ lookupTimeout = rand ($ this ->minimalDelayTimeout , $ this ->delayTimeout );
151
+
152
+ return $ lookupTimeout ;
153
+ }
131
154
}
0 commit comments