2022-01-12 11:20:33 +08:00
|
|
|
<?php
|
|
|
|
|
|
2022-06-16 17:49:06 +08:00
|
|
|
namespace Kiri\Server\Abstracts;
|
2022-01-12 11:20:33 +08:00
|
|
|
|
2022-06-16 17:38:22 +08:00
|
|
|
use Closure;
|
2022-10-11 15:15:04 +08:00
|
|
|
use Exception;
|
2022-01-14 16:11:23 +08:00
|
|
|
use Kiri;
|
2022-01-12 11:20:33 +08:00
|
|
|
use Kiri\Abstracts\Config;
|
2022-10-11 15:15:04 +08:00
|
|
|
use Kiri\Abstracts\Component;
|
2022-01-12 11:20:33 +08:00
|
|
|
use Kiri\Server\Contract\OnProcessInterface;
|
2022-10-11 15:15:04 +08:00
|
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
|
|
|
use Psr\Container\NotFoundExceptionInterface;
|
2022-01-12 11:20:33 +08:00
|
|
|
use Swoole\Process;
|
2022-10-11 15:15:04 +08:00
|
|
|
use Kiri\Annotation\Inject;
|
2022-06-16 17:38:22 +08:00
|
|
|
use Kiri\Di\ContainerInterface;
|
2022-10-11 15:15:04 +08:00
|
|
|
use Kiri\Events\EventProvider;
|
|
|
|
|
use Kiri\Server\ServerInterface;
|
|
|
|
|
use Kiri\Server\Events\OnServerBeforeStart;
|
2022-01-12 11:20:33 +08:00
|
|
|
|
2022-10-11 15:15:04 +08:00
|
|
|
class ProcessManager extends Component
|
2022-01-12 11:20:33 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @var array<string, Process> */
|
|
|
|
|
private array $_process = [];
|
|
|
|
|
|
|
|
|
|
|
2022-06-16 17:38:22 +08:00
|
|
|
/**
|
2022-10-11 15:15:04 +08:00
|
|
|
* @var ContainerInterface
|
2022-06-16 17:38:22 +08:00
|
|
|
*/
|
2022-10-11 15:15:04 +08:00
|
|
|
#[Inject(ContainerInterface::class)]
|
|
|
|
|
public ContainerInterface $container;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[Inject(EventProvider::class)]
|
|
|
|
|
public EventProvider $provider;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public function init(): void
|
2022-06-16 17:38:22 +08:00
|
|
|
{
|
2022-10-11 15:15:04 +08:00
|
|
|
$this->provider->on(OnServerBeforeStart::class, [$this, 'OnServerBeforeStart']);
|
2022-06-16 17:38:22 +08:00
|
|
|
}
|
2022-02-11 19:00:55 +08:00
|
|
|
|
2022-01-12 11:32:36 +08:00
|
|
|
|
2022-01-12 11:20:33 +08:00
|
|
|
/**
|
2022-10-11 15:15:04 +08:00
|
|
|
* @param OnServerBeforeStart $beforeStart
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws ContainerExceptionInterface
|
|
|
|
|
* @throws NotFoundExceptionInterface
|
2022-01-12 11:20:33 +08:00
|
|
|
*/
|
2022-10-11 15:15:04 +08:00
|
|
|
public function OnServerBeforeStart(OnServerBeforeStart $beforeStart): void
|
2022-01-12 11:20:33 +08:00
|
|
|
{
|
2022-10-11 15:15:04 +08:00
|
|
|
$server = $this->container->get(ServerInterface::class);
|
|
|
|
|
foreach ($this->_process as $process) {
|
|
|
|
|
$server->addProcess($process);
|
2022-01-12 11:20:33 +08:00
|
|
|
}
|
2022-10-11 15:15:04 +08:00
|
|
|
}
|
2022-01-12 11:32:36 +08:00
|
|
|
|
2022-06-16 17:38:22 +08:00
|
|
|
|
2022-10-11 15:15:04 +08:00
|
|
|
/**
|
|
|
|
|
* @param string|OnProcessInterface|BaseProcess $custom
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public function add(string|OnProcessInterface|BaseProcess $custom): void
|
|
|
|
|
{
|
|
|
|
|
if (is_string($custom)) {
|
|
|
|
|
$custom = Kiri::getDi()->get($custom);
|
|
|
|
|
}
|
|
|
|
|
if (isset($this->process[$custom->getName()])) {
|
|
|
|
|
throw new Exception('Process(' . $custom->getName() . ') is exists.');
|
|
|
|
|
}
|
|
|
|
|
$this->_process[$custom->getName()] = new Process(function (Process $process) use ($custom) {
|
|
|
|
|
set_env('environmental', Kiri::PROCESS);
|
|
|
|
|
$system = sprintf('[%s].Custom Process', Config::get('id', 'system-service'));
|
|
|
|
|
Kiri::getLogger()->alert($system . ' ' . $custom->getName() . ' start.');
|
|
|
|
|
if (Kiri::getPlatform()->isLinux()) {
|
|
|
|
|
$process->name($system . '[' . $process->pid . '].' . $custom->getName());
|
|
|
|
|
}
|
|
|
|
|
$custom->onSigterm()->process($process);
|
|
|
|
|
},
|
|
|
|
|
$custom->getRedirectStdinAndStdout(),
|
|
|
|
|
$custom->getPipeType(),
|
|
|
|
|
$custom->isEnableCoroutine()
|
2022-06-16 17:38:22 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-06-20 18:14:25 +08:00
|
|
|
/**
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function shutdown(): void
|
|
|
|
|
{
|
|
|
|
|
foreach ($this->_process as $process) {
|
2022-06-20 18:27:25 +08:00
|
|
|
Process::kill($process->pid, 0) && Process::kill($process->pid, 15);
|
2022-06-20 18:14:25 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-06-16 17:38:22 +08:00
|
|
|
/**
|
2022-06-22 18:43:36 +08:00
|
|
|
* @param BaseProcess $customProcess
|
2022-06-16 17:38:22 +08:00
|
|
|
* @return Closure
|
|
|
|
|
*/
|
2022-06-22 18:43:36 +08:00
|
|
|
public function resolve(BaseProcess $customProcess): Closure
|
2022-06-16 17:38:22 +08:00
|
|
|
{
|
2022-06-22 18:43:36 +08:00
|
|
|
return static function (Process $process) use ($customProcess) {
|
2022-06-16 17:38:22 +08:00
|
|
|
set_env('environmental', Kiri::PROCESS);
|
2022-06-22 18:43:36 +08:00
|
|
|
$system = sprintf('[%s].Custom Process', Config::get('id', 'system-service'));
|
|
|
|
|
Kiri::getLogger()->alert($system . ' ' . $customProcess->getName() . ' start.');
|
2022-06-16 17:38:22 +08:00
|
|
|
if (Kiri::getPlatform()->isLinux()) {
|
2022-10-11 15:15:04 +08:00
|
|
|
$process->name($system . '[' . $process->pid . '].' . $customProcess->getName());
|
2022-06-16 17:38:22 +08:00
|
|
|
}
|
|
|
|
|
$customProcess->onSigterm()->process($process);
|
|
|
|
|
};
|
2022-02-11 19:00:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string|null $name
|
|
|
|
|
* @param string $tag
|
2022-02-14 18:05:50 +08:00
|
|
|
* @return array|Process|null
|
2022-02-11 19:00:55 +08:00
|
|
|
*/
|
|
|
|
|
public function get(?string $name = null, string $tag = 'default'): array|Process|null
|
|
|
|
|
{
|
|
|
|
|
$process = $this->_process[$tag] ?? null;
|
|
|
|
|
if (empty($process)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
if (!empty($name)) {
|
|
|
|
|
if (!isset($process[$name])) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return $process[$name];
|
|
|
|
|
}
|
|
|
|
|
return $process;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2022-06-16 17:38:22 +08:00
|
|
|
public function stop(): void
|
2022-02-11 19:00:55 +08:00
|
|
|
{
|
|
|
|
|
foreach ($this->_process as $process) {
|
2022-06-20 18:18:38 +08:00
|
|
|
Process::kill($process->pid, 0) && Process::kill($process->pid, 15);
|
2022-02-11 19:00:55 +08:00
|
|
|
}
|
2022-01-12 11:20:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2022-06-17 12:33:14 +08:00
|
|
|
* @param array|null $processes
|
2022-06-16 17:38:22 +08:00
|
|
|
* @return void
|
2022-10-11 15:15:04 +08:00
|
|
|
* @throws Exception
|
2022-01-12 11:20:33 +08:00
|
|
|
*/
|
2022-10-11 15:15:04 +08:00
|
|
|
public function batch(?array $processes): void
|
2022-01-12 11:20:33 +08:00
|
|
|
{
|
2022-06-17 12:33:14 +08:00
|
|
|
if (empty($processes)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-01-12 11:20:33 +08:00
|
|
|
foreach ($processes as $process) {
|
2022-10-11 15:15:04 +08:00
|
|
|
$this->add($process);
|
2022-01-12 11:20:33 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $message
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2022-10-11 15:15:04 +08:00
|
|
|
public function push(string $name, string $message): void
|
2022-01-12 11:20:33 +08:00
|
|
|
{
|
2022-10-11 15:15:04 +08:00
|
|
|
if (!isset($this->_process[$name])) {
|
|
|
|
|
return;
|
2022-01-12 11:20:33 +08:00
|
|
|
}
|
2022-10-11 15:15:04 +08:00
|
|
|
$process = $this->_process[$name];
|
|
|
|
|
$process->write($message);
|
2022-01-12 11:20:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|