mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-23 08:35:35 +08:00
update to 3.0.0-alpha2 (build 610): refactor driver
This commit is contained in:
@@ -4,15 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command;
|
||||
|
||||
use ArrayIterator;
|
||||
use League\CLImate\CLImate;
|
||||
use Phar;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Console\TermColor;
|
||||
use ZM\Utils\DataProvider;
|
||||
|
||||
class BuildCommand extends Command
|
||||
{
|
||||
@@ -20,10 +15,8 @@ class BuildCommand extends Command
|
||||
protected static $defaultName = 'build';
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
* 配置
|
||||
*/
|
||||
private $output;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Build an ".phar" file | 将项目构建一个phar包');
|
||||
@@ -34,8 +27,9 @@ class BuildCommand extends Command
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
/* TODO
|
||||
$this->output = $output;
|
||||
$target_dir = $input->getOption('target') ?? (WORKING_DIR);
|
||||
$target_dir = $input->getOption('target') ?? WORKING_DIR;
|
||||
if (mb_strpos($target_dir, '../')) {
|
||||
$target_dir = realpath($target_dir);
|
||||
}
|
||||
@@ -58,47 +52,49 @@ class BuildCommand extends Command
|
||||
}
|
||||
$filename = 'server.phar';
|
||||
$this->build($target_dir, $filename);
|
||||
|
||||
return 0;
|
||||
*/
|
||||
$output->writeln('<error>Not implemented.</error>');
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
private function build($target_dir, $filename)
|
||||
{
|
||||
@unlink($target_dir . $filename);
|
||||
$phar = new Phar($target_dir . $filename);
|
||||
$phar->startBuffering();
|
||||
|
||||
private function build($target_dir, $filename)
|
||||
{
|
||||
@unlink($target_dir . $filename);
|
||||
$phar = new Phar($target_dir . $filename);
|
||||
$phar->startBuffering();
|
||||
$all = DataProvider::scanDirFiles(DataProvider::getSourceRootDir(), true, true);
|
||||
|
||||
$all = DataProvider::scanDirFiles(DataProvider::getSourceRootDir(), true, true);
|
||||
$all = array_filter($all, function ($x) {
|
||||
$dirs = preg_match('/(^(bin|config|resources|src|vendor)\\/|^(composer\\.json|README\\.md)$)/', $x);
|
||||
return !($dirs !== 1);
|
||||
});
|
||||
|
||||
$all = array_filter($all, function ($x) {
|
||||
$dirs = preg_match('/(^(bin|config|resources|src|vendor)\\/|^(composer\\.json|README\\.md)$)/', $x);
|
||||
return !($dirs !== 1);
|
||||
});
|
||||
sort($all);
|
||||
|
||||
sort($all);
|
||||
$archive_dir = DataProvider::getSourceRootDir();
|
||||
$map = [];
|
||||
|
||||
$archive_dir = DataProvider::getSourceRootDir();
|
||||
$map = [];
|
||||
|
||||
if (class_exists('\\League\\CLImate\\CLImate')) {
|
||||
$climate = new CLImate();
|
||||
$progress = $climate->progress()->total(count($all));
|
||||
}
|
||||
foreach ($all as $k => $v) {
|
||||
$map[$v] = $archive_dir . '/' . $v;
|
||||
if (isset($progress)) {
|
||||
$progress->current($k + 1, 'Adding ' . $v);
|
||||
if (class_exists('\\League\\CLImate\\CLImate')) {
|
||||
$climate = new CLImate();
|
||||
$progress = $climate->progress()->total(count($all));
|
||||
}
|
||||
foreach ($all as $k => $v) {
|
||||
$map[$v] = $archive_dir . '/' . $v;
|
||||
if (isset($progress)) {
|
||||
$progress->current($k + 1, 'Adding ' . $v);
|
||||
}
|
||||
}
|
||||
$this->output->write('<info>Building...</info>');
|
||||
$phar->buildFromIterator(new ArrayIterator($map));
|
||||
$phar->setStub(
|
||||
"#!/usr/bin/env php\n" .
|
||||
$phar->createDefaultStub(LOAD_MODE == 0 ? 'src/entry.php' : 'vendor/zhamao/framework/src/entry.php')
|
||||
);
|
||||
$phar->stopBuffering();
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('Successfully built. Location: ' . $target_dir . "{$filename}");
|
||||
$this->output->writeln('<info>You may use `chmod +x server.phar` to let phar executable with `./` command</info>');
|
||||
}
|
||||
$this->output->write('<info>Building...</info>');
|
||||
$phar->buildFromIterator(new ArrayIterator($map));
|
||||
$phar->setStub(
|
||||
"#!/usr/bin/env php\n" .
|
||||
$phar->createDefaultStub(LOAD_MODE == 0 ? 'src/entry.php' : 'vendor/zhamao/framework/src/entry.php')
|
||||
);
|
||||
$phar->stopBuffering();
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('Successfully built. Location: ' . $target_dir . "{$filename}");
|
||||
$this->output->writeln('<info>You may use `chmod +x server.phar` to let phar executable with `./` command</info>');
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class CheckConfigCommand extends Command
|
||||
return 1;
|
||||
}
|
||||
$current_cfg = getcwd() . '/config/';
|
||||
$remote_cfg = include_once FRAMEWORK_ROOT_DIR . '/config/global.php';
|
||||
$remote_cfg = include_once FRAMEWORK_ROOT_DIR . '/config/global_old.php';
|
||||
if (file_exists($current_cfg . 'global.php')) {
|
||||
$this->check($remote_cfg, 'global.php', $output);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Config\ZMConfig;
|
||||
use ZM\Utils\DataProvider;
|
||||
|
||||
class SystemdGenerateCommand extends Command
|
||||
{
|
||||
@@ -22,7 +21,7 @@ class SystemdGenerateCommand extends Command
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config');
|
||||
ZMConfig::setDirectory(SOURCE_ROOT_DIR . '/config');
|
||||
$path = $this->generate();
|
||||
$output->writeln('<info>成功生成 systemd 文件,位置:' . $path . '</info>');
|
||||
$output->writeln('<info>有关如何使用 systemd 配置文件,请访问 `https://github.com/zhamao-robot/zhamao-framework/issues/36`</info>');
|
||||
@@ -38,8 +37,7 @@ class SystemdGenerateCommand extends Command
|
||||
global $argv;
|
||||
$s .= "\nExecStart=" . PHP_BINARY . " {$argv[0]} server";
|
||||
$s .= "\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n";
|
||||
@mkdir(getcwd() . '/resources/');
|
||||
file_put_contents(ZMConfig::get('global', 'zm_data') . 'zhamao.service', $s);
|
||||
return ZMConfig::get('global', 'zm_data') . 'zhamao.service';
|
||||
file_put_contents(WORKING_DIR . '/zhamao.service', $s);
|
||||
return WORKING_DIR . '/zhamao.service';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class InitCommand extends Command
|
||||
$info = pathinfo($file);
|
||||
@mkdir($base_path . $info['dirname'], 0777, true);
|
||||
echo 'Copying ' . $file . PHP_EOL;
|
||||
$package_name = (json_decode(file_get_contents(__DIR__ . '/../../../composer.json'), true)['name']);
|
||||
$package_name = json_decode(file_get_contents(__DIR__ . '/../../../composer.json'), true)['name'];
|
||||
copy($base_path . '/vendor/' . $package_name . $file, $base_path . $file);
|
||||
} else {
|
||||
echo 'Skipping ' . $file . ' , file exists.' . PHP_EOL;
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command\Module;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Config\ZMConfig;
|
||||
use ZM\Console\Console;
|
||||
use ZM\Utils\DataProvider;
|
||||
|
||||
abstract class ModuleCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->addOption('env', null, InputOption::VALUE_REQUIRED, '设置环境类型 (production, development, staging)', '');
|
||||
$this->addOption('log-theme', null, InputOption::VALUE_REQUIRED, '改变终端的主题配色', 'default');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config');
|
||||
ZMConfig::setEnv($input->getOption('env'));
|
||||
if (ZMConfig::get('global') === false) {
|
||||
exit(zm_internal_errcode('E00007') . 'Global config load failed: ' . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n");
|
||||
}
|
||||
|
||||
// 定义常量
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once DataProvider::getFrameworkRootDir() . '/src/ZM/global_defines.php';
|
||||
|
||||
Console::init(
|
||||
ZMConfig::get('global', 'info_level') ?? 2,
|
||||
null,
|
||||
$input->getOption('log-theme'),
|
||||
($o = ZMConfig::get('console_color')) === false ? [] : $o
|
||||
);
|
||||
|
||||
$timezone = ZMConfig::get('global', 'timezone') ?? 'Asia/Shanghai';
|
||||
date_default_timezone_set($timezone);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command\Module;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Console\Console;
|
||||
use ZM\Exception\ZMException;
|
||||
use ZM\Utils\DataProvider;
|
||||
use ZM\Utils\Manager\ModuleManager;
|
||||
|
||||
class ModuleListCommand extends ModuleCommand
|
||||
{
|
||||
// the name of the command (the part after "bin/console")
|
||||
protected static $defaultName = 'module:list';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setDescription('查看所有模块信息');
|
||||
$this->setHelp('此功能将会把炸毛框架的模块列举出来。');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ZMException
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
parent::execute($input, $output);
|
||||
|
||||
$list = ModuleManager::getConfiguredModules();
|
||||
|
||||
foreach ($list as $v) {
|
||||
echo '[' . Console::setColor($v['name'], 'green') . ']' . PHP_EOL;
|
||||
$out_list = ['类型' => '源码(source)'];
|
||||
if (isset($v['version'])) {
|
||||
$out_list['版本'] = $v['version'];
|
||||
}
|
||||
if (isset($v['description'])) {
|
||||
$out_list['描述'] = $v['description'];
|
||||
}
|
||||
$out_list['目录'] = str_replace(DataProvider::getSourceRootDir() . '/', '', $v['module-path']);
|
||||
$this->printList($out_list);
|
||||
}
|
||||
if ($list === []) {
|
||||
echo Console::setColor('没有发现已编写打包配置文件(zm.json)的模块!', 'yellow') . PHP_EOL;
|
||||
}
|
||||
$list = ModuleManager::getPackedModules();
|
||||
foreach ($list as $v) {
|
||||
echo '[' . Console::setColor($v['name'], 'gold') . ']' . PHP_EOL;
|
||||
$out_list = ['类型' => '模块包(phar)'];
|
||||
if (isset($v['module-config']['version'])) {
|
||||
$out_list['版本'] = $v['module-config']['version'];
|
||||
}
|
||||
if (isset($v['module-config']['description'])) {
|
||||
$out_list['描述'] = $v['module-config']['description'];
|
||||
}
|
||||
$out_list['位置'] = str_replace(DataProvider::getSourceRootDir() . '/', '', $v['phar-path']);
|
||||
$this->printList($out_list);
|
||||
}
|
||||
if ($list === []) {
|
||||
echo Console::setColor('没有发现已打包且装载的模块!', 'yellow') . PHP_EOL;
|
||||
}
|
||||
|
||||
$list = ModuleManager::getComposerModules();
|
||||
foreach ($list as $v) {
|
||||
echo '[' . Console::setColor($v['name'], 'blue') . ']' . PHP_EOL;
|
||||
$out_list = ['类型' => 'Composer库(composer)'];
|
||||
$out_list['包名'] = $v['composer-name'];
|
||||
$out_list['目录'] = str_replace(DataProvider::getSourceRootDir() . '/', '', $v['module-path']);
|
||||
if (isset($v['version'])) {
|
||||
$out_list['版本'] = $v['version'];
|
||||
}
|
||||
if (isset($v['description'])) {
|
||||
$out_list['描述'] = $v['description'];
|
||||
}
|
||||
$out_list['命名空间'] = $v['namespace'];
|
||||
$this->printList($out_list);
|
||||
}
|
||||
if ($list === []) {
|
||||
echo Console::setColor('没有发现Composer模块!', 'yellow') . PHP_EOL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function printList($list)
|
||||
{
|
||||
foreach ($list as $k => $v) {
|
||||
echo "\t" . $k . ': ' . Console::setColor($v, 'yellow') . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command\Module;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Console\Console;
|
||||
use ZM\Exception\ZMException;
|
||||
use ZM\Utils\DataProvider;
|
||||
use ZM\Utils\Manager\ModuleManager;
|
||||
|
||||
class ModulePackCommand extends ModuleCommand
|
||||
{
|
||||
// the name of the command (the part after "bin/console")
|
||||
protected static $defaultName = 'module:pack';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->addArgument('module-name', InputArgument::REQUIRED);
|
||||
$this->setDescription('将配置好的模块构建一个phar包');
|
||||
$this->setHelp('此功能将会把炸毛框架的模块打包为".phar",供发布和执行。');
|
||||
$this->addOption('target', 'D', InputOption::VALUE_REQUIRED, 'Output Directory | 指定输出目录');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ZMException
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
parent::execute($input, $output);
|
||||
$list = ModuleManager::getConfiguredModules();
|
||||
if (!isset($list[$input->getArgument('module-name')])) {
|
||||
$output->writeln('<error>不存在模块 ' . $input->getArgument('module-name') . ' !</error>');
|
||||
return 1;
|
||||
}
|
||||
$result = ModuleManager::packModule($list[$input->getArgument('module-name')], $input->getOption('target') ?? (DataProvider::getDataFolder() . '/output'));
|
||||
if ($result) {
|
||||
Console::success('打包完成!');
|
||||
} else {
|
||||
Console::error('打包失败!');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command\Module;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Console\Console;
|
||||
use ZM\Utils\Manager\ModuleManager;
|
||||
|
||||
class ModuleUnpackCommand extends ModuleCommand
|
||||
{
|
||||
// the name of the command (the part after "bin/console")
|
||||
protected static $defaultName = 'module:unpack';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->addOption('overwrite-light-cache', null, null, '覆盖现有的LightCache项目');
|
||||
$this->addOption('overwrite-zm-data', null, null, '覆盖现有的zm_data文件');
|
||||
$this->addOption('overwrite-source', null, null, '覆盖现有的源码文件');
|
||||
$this->addOption('ignore-depends', null, null, '解包时忽略检查依赖');
|
||||
$this->addArgument('module-name', InputArgument::REQUIRED, '模块名称');
|
||||
$this->setDescription('解包一个phar模块到src目录');
|
||||
$this->setHelp('此功能将phar格式的模块包解包到src目录下。');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
parent::execute($input, $output);
|
||||
|
||||
$list = ModuleManager::getPackedModules();
|
||||
if (!isset($list[$input->getArgument('module-name')])) {
|
||||
$output->writeln('<error>不存在打包的模块 ' . $input->getArgument('module-name') . ' !</error>');
|
||||
return 1;
|
||||
}
|
||||
$result = ModuleManager::unpackModule($list[$input->getArgument('module-name')], $input->getOptions());
|
||||
if ($result) {
|
||||
Console::success('解压完成!');
|
||||
} else {
|
||||
Console::error('解压失败!');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command;
|
||||
|
||||
use Swoole\Atomic;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Http\Server;
|
||||
use Swoole\Process;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Config\ZMConfig;
|
||||
use ZM\Console\Console;
|
||||
use ZM\Logger\TablePrinter;
|
||||
use ZM\Store\ZMAtomic;
|
||||
use ZM\Utils\DataProvider;
|
||||
use ZM\Utils\HttpUtil;
|
||||
|
||||
class PureHttpCommand extends Command
|
||||
{
|
||||
// the name of the command (the part after "bin/console")
|
||||
protected static $defaultName = 'simple-http-server';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Run a simple http server | 启动一个简单的文件 HTTP 服务器');
|
||||
$this->setHelp('直接运行可以启动');
|
||||
$this->addArgument('dir', InputArgument::REQUIRED, 'Your directory');
|
||||
$this->addOption('host', 'H', InputOption::VALUE_REQUIRED, '启动监听地址');
|
||||
$this->addOption('port', 'P', InputOption::VALUE_REQUIRED, '启动监听地址的端口');
|
||||
// ...
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$tty_width = explode(' ', trim(exec('stty size')))[1];
|
||||
if (realpath($input->getArgument('dir') ?? '.') === false) {
|
||||
$output->writeln('<error>Directory error(' . ($input->getArgument('dir') ?? '.') . '): no such file or directory.</error>');
|
||||
return self::FAILURE;
|
||||
}
|
||||
ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config');
|
||||
$global = ZMConfig::get('global');
|
||||
$host = $input->getOption('host') ?? $global['host'];
|
||||
$port = $input->getOption('port') ?? $global['port'];
|
||||
|
||||
$index = ['index.html', 'index.htm'];
|
||||
$out = [
|
||||
'listen' => $host . ':' . $port,
|
||||
'version' => ZM_VERSION,
|
||||
'web_root' => realpath($input->getArgument('dir') ?? '.'),
|
||||
'index' => implode(',', $index),
|
||||
];
|
||||
$printer = new TablePrinter($out);
|
||||
$printer->printAll();
|
||||
$server = new Server($host, $port);
|
||||
$server->set(ZMConfig::get('global', 'swoole'));
|
||||
Console::init(2, $server);
|
||||
ZMAtomic::$atomics['request'] = [];
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
ZMAtomic::$atomics['request'][$i] = new Atomic(0);
|
||||
}
|
||||
$server->on('request', function (Request $request, Response $response) use ($input, $index, $server) {
|
||||
ZMAtomic::$atomics['request'][$server->worker_id]->add(1);
|
||||
HttpUtil::handleStaticPage(
|
||||
$request->server['request_uri'],
|
||||
$response,
|
||||
[
|
||||
'document_root' => realpath($input->getArgument('dir') ?? '.'),
|
||||
'document_index' => $index,
|
||||
]
|
||||
);
|
||||
// echo "\r" . Coroutine::stats()["coroutine_peak_num"];
|
||||
});
|
||||
$server->on('start', function ($server) {
|
||||
Process::signal(SIGINT, function () use ($server) {
|
||||
echo "\r";
|
||||
logger()->notice('服务器收到中断信号 SIGINT,正在停止');
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$num = ZMAtomic::$atomics['request'][$i]->get();
|
||||
if ($num != 0) {
|
||||
echo "[{$i}]: " . $num . "\n";
|
||||
}
|
||||
}
|
||||
$server->shutdown();
|
||||
$server->stop();
|
||||
});
|
||||
logger()->notice('服务器已启动,请使用 Ctrl+C 以停止。');
|
||||
});
|
||||
$server->start();
|
||||
// return this if there was no problem running the command
|
||||
// (it's equivalent to returning int(0))
|
||||
return 0;
|
||||
// or return this if some error happened during the execution
|
||||
// (it's equivalent to returning int(1))
|
||||
// return 1;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Exception\ZMKnownException;
|
||||
use ZM\Utils\Manager\ProcessManager;
|
||||
use ZM\Process\ProcessStateManager;
|
||||
|
||||
abstract class ServerCommand extends Command
|
||||
{
|
||||
@@ -19,11 +19,12 @@ abstract class ServerCommand extends Command
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$file = ProcessManager::getProcessState(ZM_PROCESS_MASTER);
|
||||
$file = ProcessStateManager::getProcessState(ZM_PROCESS_MASTER);
|
||||
/* @noinspection PhpComposerExtensionStubsInspection */
|
||||
if ($file === false || posix_getsid(intval($file['pid'])) === false) {
|
||||
$output->writeln('<comment>未检测到正在运行的守护进程或框架进程!</comment>');
|
||||
if (ProcessManager::isStateEmpty()) {
|
||||
ProcessManager::removeProcessState(ZM_PROCESS_MASTER);
|
||||
if (ProcessStateManager::isStateEmpty()) {
|
||||
ProcessStateManager::removeProcessState(ZM_PROCESS_MASTER);
|
||||
} else {
|
||||
$output->writeln('<comment>检测到可能残留的守护进程或框架进程,请使用命令关闭:server:stop --force</comment>');
|
||||
}
|
||||
|
||||
@@ -4,24 +4,24 @@ declare(strict_types=1);
|
||||
|
||||
namespace ZM\Command\Server;
|
||||
|
||||
use Symfony\Component\Console\Input\InputDefinition;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Exception\ConfigException;
|
||||
use ZM\Exception\InitException;
|
||||
use ZM\Exception\ZMKnownException;
|
||||
use ZM\Framework;
|
||||
use ZM\Utils\Manager\ProcessManager;
|
||||
use ZM\Process\ProcessStateManager;
|
||||
|
||||
class ServerStartCommand extends ServerCommand
|
||||
{
|
||||
protected static $defaultName = 'server';
|
||||
|
||||
public static function exportDefinition(): InputDefinition
|
||||
public static function exportOptionArray(): array
|
||||
{
|
||||
$cmd = new self();
|
||||
$cmd->configure();
|
||||
return $cmd->getDefinition();
|
||||
return array_map(function ($x) { return $x->getDefault(); }, $cmd->getDefinition()->getOptions());
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
@@ -29,7 +29,10 @@ class ServerStartCommand extends ServerCommand
|
||||
$this->setAliases(['server:start']);
|
||||
$this->setDefinition([
|
||||
new InputOption('debug-mode', 'D', null, '开启调试模式 (这将关闭协程化)'),
|
||||
new InputOption('config-dir', null, InputOption::VALUE_REQUIRED, '指定其他配置文件目录'),
|
||||
new InputOption('driver', null, InputOption::VALUE_REQUIRED, '指定驱动类型'),
|
||||
new InputOption('log-debug', null, null, '调整消息等级到debug (log-level=4)'),
|
||||
new InputOption('log-level', null, InputOption::VALUE_REQUIRED, '调整消息等级到debug (log-level=4)'),
|
||||
new InputOption('log-verbose', null, null, '调整消息等级到verbose (log-level=3)'),
|
||||
new InputOption('log-info', null, null, '调整消息等级到info (log-level=2)'),
|
||||
new InputOption('log-warning', null, null, '调整消息等级到warning (log-level=1)'),
|
||||
@@ -59,22 +62,26 @@ class ServerStartCommand extends ServerCommand
|
||||
|
||||
/**
|
||||
* @throws ZMKnownException
|
||||
* @throws ConfigException
|
||||
* @throws ConfigException|InitException
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
if (($opt = $input->getOption('env')) !== null) {
|
||||
// 这段用于config的环境解析,但显然不是很好的方式,应该改成一个独立的方法,不应该在这里检查,但暂时搁置,TODO
|
||||
/* if (($opt = $input->getOption('env')) !== null) {
|
||||
if (!in_array($opt, ['production', 'staging', 'development', ''])) {
|
||||
$output->writeln('<error> "--env" option only accept production, development, staging and [empty] ! </error>');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
$state = ProcessManager::getProcessState(ZM_PROCESS_MASTER);
|
||||
if (!$input->getOption('no-state-check')) {
|
||||
if (is_array($state) && posix_getsid($state['pid'] ?? -1) !== false) {
|
||||
$output->writeln("<error>检测到已经在 pid: {$state['pid']} 进程启动了框架!</error>");
|
||||
$output->writeln('<error>不可以同时启动两个框架!</error>');
|
||||
return 1;
|
||||
}*/
|
||||
if (\OneBot\Driver\Process\ProcessManager::isSupportedMultiProcess()) {
|
||||
$state = ProcessStateManager::getProcessState(ZM_PROCESS_MASTER);
|
||||
if (!$input->getOption('no-state-check')) {
|
||||
if (is_array($state) && posix_getsid($state['pid'] ?? -1) !== false) {
|
||||
$output->writeln("<error>检测到已经在 pid: {$state['pid']} 进程启动了框架!</error>");
|
||||
$output->writeln('<error>不可以同时启动两个框架!</error>');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
(new Framework($input->getOptions()))->start();
|
||||
|
||||
@@ -8,8 +8,8 @@ use Swoole\Process;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use ZM\Utils\DataProvider;
|
||||
use ZM\Utils\Manager\ProcessManager;
|
||||
use ZM\Process\ProcessStateManager;
|
||||
use ZM\Store\FileSystem;
|
||||
|
||||
class ServerStopCommand extends ServerCommand
|
||||
{
|
||||
@@ -26,8 +26,8 @@ class ServerStopCommand extends ServerCommand
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
if ($input->getOption('force') !== false) {
|
||||
$file_path = _zm_pid_dir();
|
||||
$list = DataProvider::scanDirFiles($file_path, false, true);
|
||||
$file_path = ZM_PID_DIR;
|
||||
$list = FileSystem::scanDirFiles($file_path, false, true);
|
||||
foreach ($list as $file) {
|
||||
$name = explode('.', $file);
|
||||
if (end($name) == 'pid') {
|
||||
@@ -46,7 +46,7 @@ class ServerStopCommand extends ServerCommand
|
||||
Process::kill(intval($this->daemon_file['pid']), SIGTERM);
|
||||
}
|
||||
$i = 10;
|
||||
while (ProcessManager::getProcessState(ZM_PROCESS_MASTER) !== false && $i > 0) {
|
||||
while (ProcessStateManager::getProcessState(ZM_PROCESS_MASTER) !== false && $i > 0) {
|
||||
sleep(1);
|
||||
--$i;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user