@@ -10,10 +10,11 @@ diff -Naur a/app/etc/di.xml b/app/etc/di.xml
1010 <preference for="Magento\Framework\Api\AttributeTypeResolverInterface" type="Magento\Framework\Reflection\AttributeTypeResolver" />
1111 <preference for="Magento\Framework\Api\Search\SearchResultInterface" type="Magento\Framework\Api\Search\SearchResult" />
1212 <preference for="Magento\Framework\Api\Search\SearchCriteriaInterface" type="Magento\Framework\Api\Search\SearchCriteria"/>
13- diff -Naur a/vendor/magento/framework/Lock/Backend/FileLock.php b/vendor/magento/framework/Lock/Backend/FileLock.php
13+ diff --git a/vendor/magento/framework/Lock/Backend/FileLock.php b/vendor/magento/framework/Lock/Backend/FileLock.php
14+ new file mode 100644
1415--- /dev/null
1516+++ b/vendor/magento/framework/Lock/Backend/FileLock.php
16- @@ -0,0 +1,194 @@
17+ @@ -0,0 +1,196 @@
1718+ <?php
1819+ /**
1920+ * Copyright © Magento, Inc. All rights reserved.
@@ -107,6 +108,7 @@ diff -Naur a/vendor/magento/framework/Lock/Backend/FileLock.php b/vendor/magento
107108+
108109+ while (!$this->tryToLock($fileResource)) {
109110+ if (!$skipDeadline && $deadline <= microtime(true)) {
111+ + $this->tryToUnlock($fileResource);
110112+ $this->fileDriver->fileClose($fileResource);
111113+ return false;
112114+ }
@@ -140,6 +142,7 @@ diff -Naur a/vendor/magento/framework/Lock/Backend/FileLock.php b/vendor/magento
140142+ } else {
141143+ $result = true;
142144+ }
145+ + $this->tryToUnlock($fileResource);
143146+ $this->fileDriver->fileClose($fileResource);
144147+ }
145148+ } catch (FileSystemException $exception) {
@@ -208,6 +211,7 @@ diff -Naur a/vendor/magento/framework/Lock/Backend/FileLock.php b/vendor/magento
208211+ }
209212+ }
210213+ }
214+
211215diff -Naur a/vendor/magento/framework/Lock/Backend/Zookeeper.php b/vendor/magento/framework/Lock/Backend/Zookeeper.php
212216--- /dev/null
213217+++ b/vendor/magento/framework/Lock/Backend/Zookeeper.php
@@ -1053,3 +1057,142 @@ diff -Naur a/setup/src/Magento/Setup/Model/ConfigOptionsList/Lock.php b/setup/sr
10531057+ }
10541058+ }
10551059+ }
1060+ diff -Nuar a/vendor/magento/framework/Lock/Backend/Cache.php b/vendor/magento/framework/Lock/Backend/Cache.php
1061+ new file mode 100644
1062+ --- /dev/null
1063+ +++ b/vendor/magento/framework/Lock/Backend/Cache.php
1064+ @@ -0,0 +1,134 @@
1065+ + <?php
1066+ + /**
1067+ + * Copyright © Magento, Inc. All rights reserved.
1068+ + * See COPYING.txt for license details.
1069+ + */
1070+ + declare(strict_types=1);
1071+ +
1072+ + namespace Magento\Framework\Lock\Backend;
1073+ +
1074+ + use Magento\Framework\Cache\FrontendInterface;
1075+ +
1076+ + /**
1077+ + * Implementation of the lock manager on the basis of the caching system.
1078+ + */
1079+ + class Cache implements \Magento\Framework\Lock\LockManagerInterface
1080+ + {
1081+ + /**
1082+ + * Prefix for marking that key is locked or not.
1083+ + */
1084+ + const LOCK_PREFIX = 'LOCKED_RECORD_INFO_';
1085+ +
1086+ + /**
1087+ + * @var FrontendInterface
1088+ + */
1089+ + private $cache;
1090+ +
1091+ + /**
1092+ + * Sign for locks, helps to avoid removing a lock that was created by another client
1093+ + *
1094+ + * @string
1095+ + */
1096+ + private $lockSign;
1097+ +
1098+ + /**
1099+ + * @param FrontendInterface $cache
1100+ + */
1101+ + public function __construct(FrontendInterface $cache)
1102+ + {
1103+ + $this->cache = $cache;
1104+ + $this->lockSign = $this->generateLockSign();
1105+ + }
1106+ +
1107+ + /**
1108+ + * @inheritdoc
1109+ + */
1110+ + public function lock(string $name, int $timeout = -1): bool
1111+ + {
1112+ + if (empty($this->lockSign)) {
1113+ + $this->lockSign = $this->generateLockSign();
1114+ + }
1115+ +
1116+ + $data = $this->cache->load($this->getIdentifier($name));
1117+ +
1118+ + if (false !== $data) {
1119+ + return false;
1120+ + }
1121+ +
1122+ + $timeout = $timeout <= 0 ? null : $timeout;
1123+ + $this->cache->save($this->lockSign, $this->getIdentifier($name), [], $timeout);
1124+ +
1125+ + $data = $this->cache->load($this->getIdentifier($name));
1126+ +
1127+ + if ($data === $this->lockSign) {
1128+ + return true;
1129+ + }
1130+ +
1131+ + return false;
1132+ + }
1133+ +
1134+ + /**
1135+ + * @inheritdoc
1136+ + */
1137+ + public function unlock(string $name): bool
1138+ + {
1139+ + if (empty($this->lockSign)) {
1140+ + return false;
1141+ + }
1142+ +
1143+ + $data = $this->cache->load($this->getIdentifier($name));
1144+ +
1145+ + if (false === $data) {
1146+ + return false;
1147+ + }
1148+ +
1149+ + $removeResult = false;
1150+ + if ($data === $this->lockSign) {
1151+ + $removeResult = (bool)$this->cache->remove($this->getIdentifier($name));
1152+ + }
1153+ +
1154+ + return $removeResult;
1155+ + }
1156+ +
1157+ + /**
1158+ + * @inheritdoc
1159+ + */
1160+ + public function isLocked(string $name): bool
1161+ + {
1162+ + return (bool)$this->cache->test($this->getIdentifier($name));
1163+ + }
1164+ +
1165+ + /**
1166+ + * Get cache locked identifier based on cache identifier.
1167+ + *
1168+ + * @param string $cacheIdentifier
1169+ + * @return string
1170+ + */
1171+ + private function getIdentifier(string $cacheIdentifier): string
1172+ + {
1173+ + return self::LOCK_PREFIX . $cacheIdentifier;
1174+ + }
1175+ +
1176+ + /**
1177+ + * Function that generates lock sign that helps to avoid removing a lock that was created by another client.
1178+ + *
1179+ + * @return string
1180+ + */
1181+ + private function generateLockSign()
1182+ + {
1183+ + $sign = implode(
1184+ + '-',
1185+ + [
1186+ + \getmypid(), \crc32(\gethostname())
1187+ + ]
1188+ + );
1189+ +
1190+ + try {
1191+ + $sign .= '-' . \bin2hex(\random_bytes(4));
1192+ + } catch (\Exception $e) {
1193+ + $sign .= '-' . \uniqid('-uniqid-');
1194+ + }
1195+ +
1196+ + return $sign;
1197+ + }
1198+ + }
0 commit comments