PidConsumerManager.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\MessageQueue\Model\Cron\ConsumersRunner;
  7. use Magento\Framework\App\Filesystem\DirectoryList;
  8. use Magento\Framework\Filesystem\Directory\WriteInterface;
  9. use Magento\Framework\Filesystem\Directory\ReadInterface;
  10. use Magento\Framework\Filesystem;
  11. use Magento\Framework\Exception\FileSystemException;
  12. /**
  13. * The class for checking status of process by PID
  14. */
  15. class PidConsumerManager
  16. {
  17. /**
  18. * Extension of PID file
  19. * @deprecated Moved to the correct responsibility area
  20. * @see \Magento\MessageQueue\Model\Cron\ConsumersRunner::PID_FILE_EXT
  21. */
  22. const PID_FILE_EXT = '.pid';
  23. /**
  24. * The class for working with FS
  25. *
  26. * @var Filesystem
  27. */
  28. private $filesystem;
  29. /**
  30. * @param Filesystem $filesystem The class for working with FS
  31. */
  32. public function __construct(Filesystem $filesystem)
  33. {
  34. $this->filesystem = $filesystem;
  35. }
  36. /**
  37. * Checks if consumer process is run by pid from pidFile
  38. *
  39. * @param string $pidFilePath The path to file with PID
  40. * @return bool Returns true if consumer process is run
  41. * @throws FileSystemException
  42. */
  43. public function isRun($pidFilePath)
  44. {
  45. $pid = $this->getPid($pidFilePath);
  46. if ($pid) {
  47. if (function_exists('posix_getpgid')) {
  48. return (bool) posix_getpgid($pid);
  49. } else {
  50. return $this->checkIsProcessExists($pid);
  51. }
  52. }
  53. return false;
  54. }
  55. /**
  56. * Checks that process is running
  57. *
  58. * If php function exec is not available throws RuntimeException
  59. * If shell command returns non-zero code and this code is not 1 throws RuntimeException
  60. *
  61. * @param int $pid A pid of process
  62. * @return bool Returns true if consumer process is run
  63. * @throws \RuntimeException
  64. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  65. */
  66. private function checkIsProcessExists($pid)
  67. {
  68. if (!function_exists('exec')) {
  69. throw new \RuntimeException('Function exec is not available');
  70. }
  71. exec(escapeshellcmd('ps -p ' . $pid), $output, $code);
  72. $code = (int) $code;
  73. switch ($code) {
  74. case 0:
  75. return true;
  76. break;
  77. case 1:
  78. return false;
  79. break;
  80. default:
  81. throw new \RuntimeException('Exec returned non-zero code', $code);
  82. break;
  83. }
  84. }
  85. /**
  86. * Returns pid by pidFile path
  87. *
  88. * @param string $pidFilePath The path to file with PID
  89. * @return int Returns pid if pid file exists for consumer else returns 0
  90. * @throws FileSystemException
  91. */
  92. public function getPid($pidFilePath)
  93. {
  94. /** @var ReadInterface $directory */
  95. $directory = $this->filesystem->getDirectoryRead(DirectoryList::VAR_DIR);
  96. if ($directory->isExist($pidFilePath)) {
  97. return (int) $directory->readFile($pidFilePath);
  98. }
  99. return 0;
  100. }
  101. /**
  102. * Saves pid of current process to file
  103. *
  104. * @param string $pidFilePath The path to file with pid
  105. * @throws FileSystemException
  106. */
  107. public function savePid($pidFilePath)
  108. {
  109. /** @var WriteInterface $directory */
  110. $directory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
  111. $directory->writeFile($pidFilePath, function_exists('posix_getpid') ? posix_getpid() : getmypid(), 'w');
  112. }
  113. }