LockerProcess.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Asset;
  7. use Magento\Framework\App\Filesystem\DirectoryList;
  8. use Magento\Framework\App\ObjectManager;
  9. use Magento\Framework\App\State;
  10. use Magento\Framework\Exception\FileSystemException;
  11. use Magento\Framework\Filesystem;
  12. use Magento\Framework\Filesystem\Directory\WriteInterface;
  13. /**
  14. * Class LockerProcess
  15. */
  16. class LockerProcess implements LockerProcessInterface
  17. {
  18. /**
  19. * File extension lock
  20. */
  21. const LOCK_EXTENSION = '.lock';
  22. /**
  23. * Max execution (locking) time for process (in seconds)
  24. */
  25. const MAX_LOCK_TIME = 30;
  26. /**
  27. * @var Filesystem
  28. */
  29. private $filesystem;
  30. /**
  31. * @var string
  32. */
  33. private $lockFilePath;
  34. /**
  35. * @var WriteInterface
  36. */
  37. private $tmpDirectory;
  38. /**
  39. * @var State
  40. */
  41. private $state;
  42. /**
  43. * Constructor
  44. *
  45. * @param Filesystem $filesystem
  46. */
  47. public function __construct(Filesystem $filesystem)
  48. {
  49. $this->filesystem = $filesystem;
  50. }
  51. /**
  52. * @inheritdoc
  53. */
  54. public function lockProcess($lockName)
  55. {
  56. if ($this->getState()->getMode() == State::MODE_PRODUCTION) {
  57. return;
  58. }
  59. $this->tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
  60. $this->lockFilePath = $this->getFilePath($lockName);
  61. while ($this->isProcessLocked()) {
  62. usleep(1000);
  63. }
  64. $this->tmpDirectory->writeFile($this->lockFilePath, time());
  65. }
  66. /**
  67. * @inheritdoc
  68. * @throws FileSystemException
  69. */
  70. public function unlockProcess()
  71. {
  72. if ($this->getState()->getMode() == State::MODE_PRODUCTION) {
  73. return;
  74. }
  75. $this->tmpDirectory->delete($this->lockFilePath);
  76. }
  77. /**
  78. * Check whether generation process has already locked
  79. *
  80. * @return bool
  81. */
  82. private function isProcessLocked()
  83. {
  84. if ($this->tmpDirectory->isExist($this->lockFilePath)) {
  85. try {
  86. $lockTime = (int)$this->tmpDirectory->readFile($this->lockFilePath);
  87. if ((time() - $lockTime) >= self::MAX_LOCK_TIME) {
  88. $this->tmpDirectory->delete($this->lockFilePath);
  89. return false;
  90. }
  91. } catch (FileSystemException $e) {
  92. return false;
  93. }
  94. return true;
  95. }
  96. return false;
  97. }
  98. /**
  99. * Get name of lock file
  100. *
  101. * @param string $name
  102. * @return string
  103. */
  104. private function getFilePath($name)
  105. {
  106. return DirectoryList::TMP . DIRECTORY_SEPARATOR . $name . self::LOCK_EXTENSION;
  107. }
  108. /**
  109. * @return State
  110. * @deprecated 100.1.1
  111. */
  112. private function getState()
  113. {
  114. if (null === $this->state) {
  115. $this->state = ObjectManager::getInstance()->get(State::class);
  116. }
  117. return $this->state;
  118. }
  119. }