Files
links/patches/application/common/service/SplitSyncConfigService.php
T

158 lines
4.3 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\service;
use think\Config;
use think\Db;
/**
* 工单云控同步相关系统配置读取
*/
class SplitSyncConfigService
{
private const DEFAULT_NODE_HOST = 'http://127.0.0.1:3001';
/**
* Node Headless 服务根地址
*/
public static function getNodeHost(): string
{
$value = self::getConfigValue('split_scrm_node_host');
$value = trim($value);
return $value !== '' ? rtrim($value, '/') : self::DEFAULT_NODE_HOST;
}
/**
* 连续同步失败多少次后自动暂停工单(0 表示不因失败暂停)
*/
public static function getFailPauseThreshold(): int
{
$value = self::getConfigValue('split_sync_fail_pause_threshold');
if ($value === '') {
return 5;
}
return max(0, (int) $value);
}
/**
* 指定工单类型的自动同步周期(分钟),0 表示不自动同步
*/
public static function getIntervalMinutes(string $ticketType): int
{
$ticketType = trim($ticketType);
if ($ticketType === '') {
return 0;
}
$key = 'split_sync_interval_' . $ticketType;
$value = self::getConfigValue($key);
return max(0, (int) $value);
}
/**
* 单次 cron 最多处理几条到期工单,避免一分钟内打满 Node Browser 槽位
*/
public static function getMaxTicketsPerCronRun(): int
{
$value = self::getConfigValue('split_sync_max_per_cron');
if ($value === '') {
return 5;
}
return max(1, min(20, (int) $value));
}
/**
* Node 通道候选池倍数(候选数 = maxPerRun × 本值)
*/
public static function getNodeCandidatePoolMultiplier(): int
{
$value = self::getConfigValue('split_sync_node_candidate_multiplier');
if ($value === '') {
return 10;
}
return max(3, min(50, (int) $value));
}
/**
* 全局 cron 锁过期秒数,防止异常退出后永久占锁
*/
public static function getCronLockTtlSeconds(): int
{
$value = self::getConfigValue('split_sync_cron_lock_ttl');
if ($value === '') {
return 1800;
}
return max(300, (int) $value);
}
/**
* Node 排队数达到该阈值时,本轮 cron 不再提交新任务
*/
public static function getNodeQueueSkipThreshold(): int
{
$value = self::getConfigValue('split_sync_node_queue_threshold');
if ($value === '') {
return 2;
}
return max(0, (int) $value);
}
/**
* 后台投递 / Cron 使用的 PHP CLI 可执行文件路径
*
* Web(FPM) 环境下 PHP_BINARY 指向 php-fpm,不能用于 think 命令。
*/
public static function getCliPhpBinary(): string
{
$configured = trim(self::getConfigValue('split_sync_cli_php'));
if ($configured !== '' && self::isUsableCliPhp($configured)) {
return $configured;
}
if (defined('PHP_BINDIR') && PHP_BINDIR !== '') {
$candidate = rtrim(PHP_BINDIR, '/\\') . DIRECTORY_SEPARATOR . 'php';
if (self::isUsableCliPhp($candidate)) {
return $candidate;
}
}
if (PHP_SAPI === 'cli' && defined('PHP_BINARY') && PHP_BINARY !== '' && self::isUsableCliPhp(PHP_BINARY)) {
return PHP_BINARY;
}
foreach (['/usr/bin/php', '/usr/local/bin/php'] as $candidate) {
if (self::isUsableCliPhp($candidate)) {
return $candidate;
}
}
return 'php';
}
/**
* 判断路径是否为可用的 PHP CLI(排除 php-fpm
*/
private static function isUsableCliPhp(string $path): bool
{
if (stripos($path, 'fpm') !== false) {
return false;
}
if ($path === 'php') {
return true;
}
return is_file($path) && is_executable($path);
}
private static function getConfigValue(string $name): string
{
$site = Config::get('site.' . $name);
if ($site !== null && $site !== '') {
return (string) $site;
}
$db = Db::name('config')->where('name', $name)->value('value');
return $db !== null ? (string) $db : '';
}
}