2021-03-28 16:09:18 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace HttpServer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use Exception;
|
|
|
|
|
use Snowflake\Abstracts\Component;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Class Shutdown
|
|
|
|
|
* @package HttpServer
|
|
|
|
|
*/
|
|
|
|
|
class Shutdown extends Component
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
2021-03-29 10:44:36 +08:00
|
|
|
private string $taskDirectory;
|
|
|
|
|
private string $workerDirectory;
|
|
|
|
|
private string $managerDirectory;
|
|
|
|
|
private string $processDirectory;
|
|
|
|
|
|
|
|
|
|
|
2021-03-29 11:32:01 +08:00
|
|
|
private array $_pids = [];
|
|
|
|
|
|
|
|
|
|
|
2021-03-29 10:44:36 +08:00
|
|
|
/**
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2021-03-29 17:00:53 +08:00
|
|
|
public function init()
|
2021-03-29 10:44:36 +08:00
|
|
|
{
|
|
|
|
|
$this->taskDirectory = storage(null, 'pid/task');
|
|
|
|
|
$this->workerDirectory = storage(null, 'pid/worker');
|
|
|
|
|
$this->managerDirectory = storage(null, 'pid/manager');
|
|
|
|
|
$this->processDirectory = storage(null, 'pid/process');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public function shutdown(): void
|
|
|
|
|
{
|
|
|
|
|
clearstatcache(storage());
|
2021-04-19 14:52:53 +08:00
|
|
|
$output = shell_exec('[ -f /.dockerenv ] && echo yes || echo no');
|
2021-04-19 14:55:44 +08:00
|
|
|
if (trim($output) === 'yes') {
|
2021-04-16 11:36:27 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2021-03-29 10:44:36 +08:00
|
|
|
|
|
|
|
|
$master_pid = Server()->setting['pid_file'] ?? PID_PATH;
|
|
|
|
|
if (file_exists($master_pid)) {
|
2021-07-06 16:25:13 +08:00
|
|
|
$this->close(file_get_contents($master_pid));
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
|
|
|
|
$this->closeOther();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关闭其他进程
|
|
|
|
|
*/
|
|
|
|
|
private function closeOther(): void
|
|
|
|
|
{
|
|
|
|
|
$this->directoryCheck($this->managerDirectory);
|
|
|
|
|
$this->directoryCheck($this->taskDirectory);
|
|
|
|
|
$this->directoryCheck($this->workerDirectory);
|
|
|
|
|
$this->directoryCheck($this->processDirectory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
* @throws Exception
|
|
|
|
|
* check server is running.
|
|
|
|
|
*/
|
2021-03-29 10:48:59 +08:00
|
|
|
public function isRunning(): bool
|
2021-03-29 10:44:36 +08:00
|
|
|
{
|
|
|
|
|
$master_pid = Server()->setting['pid_file'] ?? PID_PATH;
|
|
|
|
|
|
|
|
|
|
if (!file_exists($master_pid)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-29 10:48:59 +08:00
|
|
|
return $this->pidIsExists(file_get_contents($master_pid));
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param $content
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function pidIsExists($content): bool
|
|
|
|
|
{
|
|
|
|
|
if (intval($content) < 1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-03-29 12:13:53 +08:00
|
|
|
exec('ps -eo pid', $output);
|
|
|
|
|
$output = array_filter($output, function ($value) {
|
|
|
|
|
return intval($value);
|
|
|
|
|
});
|
2021-03-29 12:14:37 +08:00
|
|
|
return in_array(intval($content), $output);
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $path
|
2021-03-29 10:46:51 +08:00
|
|
|
* @return bool
|
2021-03-29 10:44:36 +08:00
|
|
|
*/
|
2021-03-29 10:46:51 +08:00
|
|
|
public function directoryCheck(string $path): bool
|
2021-03-29 10:44:36 +08:00
|
|
|
{
|
2021-07-06 16:25:13 +08:00
|
|
|
$values = $this->getProcessPidS($path);
|
|
|
|
|
if (empty($values)) return false;
|
|
|
|
|
|
|
|
|
|
$diff = array_diff($values, $this->getPidS());
|
|
|
|
|
foreach ($diff as $value) {
|
|
|
|
|
$this->pidIsExists($value);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param $path
|
|
|
|
|
* @return array|bool
|
|
|
|
|
*/
|
|
|
|
|
private function getProcessPidS($path): bool|array
|
|
|
|
|
{
|
|
|
|
|
$values = [];
|
2021-03-29 10:44:36 +08:00
|
|
|
$dir = new \DirectoryIterator($path);
|
|
|
|
|
if ($dir->getSize() < 1) {
|
2021-07-06 16:25:13 +08:00
|
|
|
return $values;
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
|
|
|
|
foreach ($dir as $value) {
|
|
|
|
|
if ($value->isDot()) continue;
|
|
|
|
|
|
|
|
|
|
if (!$value->valid()) continue;
|
|
|
|
|
|
2021-07-06 16:25:13 +08:00
|
|
|
$_value = file_get_contents($value->getRealPath());
|
|
|
|
|
if (empty($_value)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$values[] = intval($_value);
|
2021-07-06 16:31:51 +08:00
|
|
|
|
|
|
|
|
@unlink($value->getRealPath());
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
2021-07-06 16:25:13 +08:00
|
|
|
return $values;
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2021-07-06 16:25:13 +08:00
|
|
|
* @return array
|
2021-03-29 10:44:36 +08:00
|
|
|
*/
|
2021-07-06 16:25:13 +08:00
|
|
|
private function getPidS(): array
|
2021-03-29 10:44:36 +08:00
|
|
|
{
|
2021-07-06 16:25:13 +08:00
|
|
|
exec('ps -eo pid', $output);
|
|
|
|
|
return array_filter($output, function ($value) {
|
|
|
|
|
return intval($value);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-29 10:44:36 +08:00
|
|
|
|
2021-07-06 16:25:13 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $value
|
|
|
|
|
*/
|
|
|
|
|
public function close(mixed $value)
|
|
|
|
|
{
|
|
|
|
|
while ($this->pidIsExists($value)) {
|
|
|
|
|
exec('kill -15 ' . $value);
|
2021-07-06 16:15:27 +08:00
|
|
|
usleep(100);
|
2021-03-29 10:44:36 +08:00
|
|
|
}
|
|
|
|
|
clearstatcache($value);
|
|
|
|
|
if (file_exists($value)) {
|
|
|
|
|
@unlink($value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-28 16:09:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|