59 lines
2.3 KiB
PHP
59 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\command;
|
|
|
|
use app\common\service\assistantservice\AssistantServiceWorker;
|
|
use app\common\service\assistantservice\AssistantServiceAutomation;
|
|
use think\console\Command;
|
|
use think\console\Input;
|
|
use think\console\input\Option;
|
|
use think\console\Output;
|
|
use think\facade\Db;
|
|
|
|
final class AssistantServiceWork extends Command
|
|
{
|
|
protected function configure()
|
|
{
|
|
$this->setName('assistant-service:work')->setDescription('医助服务持久队列;未知执行结果不自动重试')
|
|
->addOption('once', null, Option::VALUE_NONE, '只处理一轮')
|
|
->addOption('sleep', null, Option::VALUE_REQUIRED, '空闲轮询间隔秒数', '3');
|
|
}
|
|
|
|
protected function execute(Input $input, Output $output): int
|
|
{
|
|
$running = true;
|
|
if (function_exists('pcntl_async_signals')) {
|
|
pcntl_async_signals(true);
|
|
pcntl_signal(SIGTERM, static function () use (&$running): void { $running = false; });
|
|
pcntl_signal(SIGINT, static function () use (&$running): void { $running = false; });
|
|
}
|
|
$pause = max(1, min(60, (int) $input->getOption('sleep')));
|
|
$worker = new AssistantServiceWorker();
|
|
try { do {
|
|
$worked = false;
|
|
try {
|
|
$this->heartbeat('working');
|
|
$worked = $worker->runOnce();
|
|
$this->heartbeat('idle');
|
|
if ($worked || $input->getOption('once')) { $output->writeln('ASSISTANT_SERVICE processed=' . ($worked ? '1' : '0')); }
|
|
} catch (\Throwable $e) {
|
|
$this->heartbeat('error');
|
|
$output->writeln('ASSISTANT_SERVICE storage_or_configuration_error');
|
|
try { Db::connect()->close(); } catch (\Throwable $ignored) {}
|
|
if ($input->getOption('once')) { return 1; }
|
|
}
|
|
if (!$input->getOption('once') && $running && !$worked) { sleep($pause); }
|
|
} while (!$input->getOption('once') && $running);
|
|
} finally { $this->heartbeat('stopped'); }
|
|
return 0;
|
|
}
|
|
|
|
private function heartbeat(string $phase): void
|
|
{
|
|
// 心跳存储故障不能改变原消费者生成/提交语义;总览将显示心跳缺失。
|
|
try { AssistantServiceAutomation::workerHeartbeat($phase); } catch (\Throwable $ignored) {}
|
|
}
|
|
}
|