3
3
* Copyright © Magento, Inc. All rights reserved.
4
4
* See COPYING.txt for license details.
5
5
*/
6
+
6
7
namespace Magento \Config \App \Config \Type ;
7
8
8
9
use Magento \Framework \App \Config \ConfigSourceInterface ;
13
14
use Magento \Config \App \Config \Type \System \Reader ;
14
15
use Magento \Framework \App \ScopeInterface ;
15
16
use Magento \Framework \Cache \FrontendInterface ;
17
+ use Magento \Framework \Cache \LockGuardedCacheLoader ;
16
18
use Magento \Framework \Lock \LockManagerInterface ;
17
19
use Magento \Framework \Serialize \SerializerInterface ;
18
20
use Magento \Store \Model \Config \Processor \Fallback ;
19
- use Magento \Store \Model \ScopeInterface as StoreScope ;
20
21
use Magento \Framework \Encryption \Encryptor ;
22
+ use Magento \Store \Model \ScopeInterface as StoreScope ;
21
23
22
24
/**
23
25
* System configuration type
24
26
*
25
27
* @api
26
28
* @since 100.1.2
27
29
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
28
31
*/
29
32
class System implements ConfigTypeInterface
30
33
{
@@ -42,22 +45,6 @@ class System implements ConfigTypeInterface
42
45
* @var string
43
46
*/
44
47
private static $ lockName = 'SYSTEM_CONFIG ' ;
45
- /**
46
- * Timeout between retrieves to load the configuration from the cache.
47
- *
48
- * Value of the variable in microseconds.
49
- *
50
- * @var int
51
- */
52
- private static $ delayTimeout = 100000 ;
53
- /**
54
- * Lifetime of the lock for write in cache.
55
- *
56
- * Value of the variable in seconds.
57
- *
58
- * @var int
59
- */
60
- private static $ lockTimeout = 42 ;
61
48
62
49
/**
63
50
* @var array
@@ -106,9 +93,9 @@ class System implements ConfigTypeInterface
106
93
private $ encryptor ;
107
94
108
95
/**
109
- * @var LockManagerInterface
96
+ * @var LockGuardedCacheLoader
110
97
*/
111
- private $ locker ;
98
+ private $ lockQuery ;
112
99
113
100
/**
114
101
* @param ConfigSourceInterface $source
@@ -122,6 +109,7 @@ class System implements ConfigTypeInterface
122
109
* @param Reader|null $reader
123
110
* @param Encryptor|null $encryptor
124
111
* @param LockManagerInterface|null $locker
112
+ * @param LockGuardedCacheLoader|null $lockQuery
125
113
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
126
114
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
127
115
*/
@@ -136,7 +124,8 @@ public function __construct(
136
124
$ configType = self ::CONFIG_TYPE ,
137
125
Reader $ reader = null ,
138
126
Encryptor $ encryptor = null ,
139
- LockManagerInterface $ locker = null
127
+ LockManagerInterface $ locker = null ,
128
+ LockGuardedCacheLoader $ lockQuery = null
140
129
) {
141
130
$ this ->postProcessor = $ postProcessor ;
142
131
$ this ->cache = $ cache ;
@@ -145,8 +134,8 @@ public function __construct(
145
134
$ this ->reader = $ reader ?: ObjectManager::getInstance ()->get (Reader::class);
146
135
$ this ->encryptor = $ encryptor
147
136
?: ObjectManager::getInstance ()->get (Encryptor::class);
148
- $ this ->locker = $ locker
149
- ?: ObjectManager::getInstance ()->get (LockManagerInterface ::class);
137
+ $ this ->lockQuery = $ lockQuery
138
+ ?: ObjectManager::getInstance ()->get (LockGuardedCacheLoader ::class);
150
139
}
151
140
152
141
/**
@@ -225,91 +214,64 @@ private function getWithParts($path)
225
214
}
226
215
227
216
/**
228
- * Make lock on data load.
229
- *
230
- * @param callable $dataLoader
231
- * @param bool $flush
232
- * @return array
233
- */
234
- private function lockedLoadData (callable $ dataLoader , bool $ flush = false ): array
235
- {
236
- $ cachedData = $ dataLoader (); //optimistic read
237
-
238
- while ($ cachedData === false && $ this ->locker ->isLocked (self ::$ lockName )) {
239
- usleep (self ::$ delayTimeout );
240
- $ cachedData = $ dataLoader ();
241
- }
242
-
243
- while ($ cachedData === false ) {
244
- try {
245
- if ($ this ->locker ->lock (self ::$ lockName , self ::$ lockTimeout )) {
246
- if (!$ flush ) {
247
- $ data = $ this ->readData ();
248
- $ this ->cacheData ($ data );
249
- $ cachedData = $ data ;
250
- } else {
251
- $ this ->cache ->clean (\Zend_Cache::CLEANING_MODE_MATCHING_TAG , [self ::CACHE_TAG ]);
252
- $ cachedData = [];
253
- }
254
- }
255
- } finally {
256
- $ this ->locker ->unlock (self ::$ lockName );
257
- }
258
-
259
- if ($ cachedData === false ) {
260
- usleep (self ::$ delayTimeout );
261
- $ cachedData = $ dataLoader ();
262
- }
263
- }
264
-
265
- return $ cachedData ;
266
- }
267
-
268
- /**
269
- * Load configuration data for all scopes
217
+ * Load configuration data for all scopes.
270
218
*
271
219
* @return array
272
220
*/
273
221
private function loadAllData ()
274
222
{
275
- return $ this -> lockedLoadData ( function () {
223
+ $ loadAction = function () {
276
224
$ cachedData = $ this ->cache ->load ($ this ->configType );
277
225
$ data = false ;
278
226
if ($ cachedData !== false ) {
279
227
$ data = $ this ->serializer ->unserialize ($ this ->encryptor ->decrypt ($ cachedData ));
280
228
}
281
229
return $ data ;
282
- });
230
+ };
231
+
232
+ return $ this ->lockQuery ->lockedLoadData (
233
+ self ::$ lockName ,
234
+ $ loadAction ,
235
+ \Closure::fromCallable ([$ this , 'readData ' ]),
236
+ \Closure::fromCallable ([$ this , 'cacheData ' ])
237
+ );
283
238
}
284
239
285
240
/**
286
- * Load configuration data for default scope
241
+ * Load configuration data for default scope.
287
242
*
288
243
* @param string $scopeType
289
244
* @return array
290
245
*/
291
246
private function loadDefaultScopeData ($ scopeType )
292
247
{
293
- return $ this -> lockedLoadData ( function () use ($ scopeType ) {
248
+ $ loadAction = function () use ($ scopeType ) {
294
249
$ cachedData = $ this ->cache ->load ($ this ->configType . '_ ' . $ scopeType );
295
250
$ scopeData = false ;
296
251
if ($ cachedData !== false ) {
297
252
$ scopeData = [$ scopeType => $ this ->serializer ->unserialize ($ this ->encryptor ->decrypt ($ cachedData ))];
298
253
}
299
254
return $ scopeData ;
300
- });
255
+ };
256
+
257
+ return $ this ->lockQuery ->lockedLoadData (
258
+ self ::$ lockName ,
259
+ $ loadAction ,
260
+ \Closure::fromCallable ([$ this , 'readData ' ]),
261
+ \Closure::fromCallable ([$ this , 'cacheData ' ])
262
+ );
301
263
}
302
264
303
265
/**
304
- * Load configuration data for a specified scope
266
+ * Load configuration data for a specified scope.
305
267
*
306
268
* @param string $scopeType
307
269
* @param string $scopeId
308
270
* @return array
309
271
*/
310
272
private function loadScopeData ($ scopeType , $ scopeId )
311
273
{
312
- return $ this -> lockedLoadData ( function () use ($ scopeType , $ scopeId ) {
274
+ $ loadAction = function () use ($ scopeType , $ scopeId ) {
313
275
$ cachedData = $ this ->cache ->load ($ this ->configType . '_ ' . $ scopeType . '_ ' . $ scopeId );
314
276
$ scopeData = false ;
315
277
if ($ cachedData === false ) {
@@ -329,7 +291,14 @@ private function loadScopeData($scopeType, $scopeId)
329
291
}
330
292
331
293
return $ scopeData ;
332
- });
294
+ };
295
+
296
+ return $ this ->lockQuery ->lockedLoadData (
297
+ self ::$ lockName ,
298
+ $ loadAction ,
299
+ \Closure::fromCallable ([$ this , 'readData ' ]),
300
+ \Closure::fromCallable ([$ this , 'cacheData ' ])
301
+ );
333
302
}
334
303
335
304
/**
@@ -371,7 +340,7 @@ private function cacheData(array $data)
371
340
}
372
341
373
342
/**
374
- * Walk nested hash map by keys from $pathParts
343
+ * Walk nested hash map by keys from $pathParts.
375
344
*
376
345
* @param array $data to walk in
377
346
* @param array $pathParts keys path
@@ -408,7 +377,7 @@ private function readData(): array
408
377
}
409
378
410
379
/**
411
- * Clean cache and global variables cache
380
+ * Clean cache and global variables cache.
412
381
*
413
382
* Next items cleared:
414
383
* - Internal property intended to store already loaded configuration data
@@ -420,11 +389,13 @@ private function readData(): array
420
389
public function clean ()
421
390
{
422
391
$ this ->data = [];
423
- $ this ->lockedLoadData (
424
- function () {
425
- return false ;
426
- },
427
- true
392
+ $ cleanAction = function () {
393
+ $ this ->cache ->clean (\Zend_Cache::CLEANING_MODE_MATCHING_TAG , [self ::CACHE_TAG ]);
394
+ };
395
+
396
+ $ this ->lockQuery ->lockedCleanData (
397
+ self ::$ lockName ,
398
+ $ cleanAction
428
399
);
429
400
}
430
401
}
0 commit comments