Files
ulthon_admin/extend/base/common/service/TimerServiceBase.php
augushong 25fab093fa feat(timer): 新增 run_type 调度、host_id 投递和日志清理
T7: TimerBase shouldExecuteTask() - main/auto/all/manual/disabled modes
    with two-phase DB row lock for auto mode
T8: TimerControllerBase - host_id param, logStart/logEnd methods
    TimerServiceBase - inject host_id into site URLs
T9: TimerLogClean command - php think admin:timer:log:clean --days=30
2026-05-26 18:33:42 +08:00

168 lines
5.2 KiB
PHP
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
namespace base\common\service;
use app\admin\model\SystemTimerConfig;
use app\common\model\VirtualModel;
use app\common\service\HostService;
class TimerServiceBase
{
protected $taskList = null;
/**
* 将配置文件中的定时任务同步到数据库.
* 仅新增不存在的记录,标记孤立记录,不覆盖 run_type/status.
*/
public static function syncConfigToDatabase(): void
{
$config_list = include app_file_path('common/command/timer/config.php');
// 提取唯一的任务名称(并发扩展会产生同名配置,需去重)
$config_names = [];
foreach ($config_list as $config_item) {
$item = static::initConfigItem($config_item);
$name = (string) $item['name'];
if ($name !== '' && !in_array($name, $config_names, true)) {
$config_names[] = $name;
}
}
// 查询已有记录
$existing = SystemTimerConfig::column('task_name');
$now = time();
// 新增:配置中有但数据库中没有的
$new_names = array_diff($config_names, $existing);
foreach ($new_names as $name) {
SystemTimerConfig::create([
'task_name' => $name,
'run_type' => 'auto',
'status' => 1,
'is_synced' => 1,
'create_time' => $now,
'update_time' => $now,
]);
}
// 已存在且仍在配置中:仅更新 is_synced=1不动 run_type/status
$still_exists = array_intersect($existing, $config_names);
foreach ($still_exists as $name) {
SystemTimerConfig::where('task_name', $name)
->update([
'is_synced' => 1,
'update_time' => $now,
]);
}
// 已存在但不在配置中:标记为孤立
$orphaned = array_diff($existing, $config_names);
foreach ($orphaned as $name) {
SystemTimerConfig::where('task_name', $name)
->update([
'is_synced' => 0,
'update_time' => $now,
]);
}
}
public static function generateAllTaskInstanceList()
{
$config_list = include app_file_path('common/command/timer/config.php');
$task_list = [];
foreach ($config_list as $config_item) {
if ($config_item['name'] == 'http_demo' && !env('adminsystem.is_demo', false)) {
continue;
}
$task_list = array_merge($task_list, static::generateTaskInstanceFromConfig($config_item));
}
return $task_list;
}
public function generateAllRequestList()
{
if ($this->taskList === null) {
$this->taskList = static::generateAllTaskInstanceList();
}
$request_list = array_filter($this->taskList, function ($item) {
return $item['type'] == 'site';
});
return $request_list;
}
public function generateAllCallList()
{
if ($this->taskList === null) {
$this->taskList = static::generateAllTaskInstanceList();
}
$request_list = array_filter($this->taskList, function ($item) {
return $item['type'] == 'call';
});
return $request_list;
}
public static function generateTaskInstanceFromConfig($config_item)
{
$config_item = static::initConfigItem($config_item);
$request_list = [];
$concurrency = $config_item['concurrency'];
for ($i = 0; $i < $concurrency; $i++) {
$target = $config_item['target'];
$params = [
'concurrency_id' => $i,
'concurrency_count' => $concurrency,
'host_id' => HostService::getNodeId(),
];
// 处理target
if ($config_item['type'] == 'site') {
$target_info = parse_url($target);
$query_params = [];
if (isset($target_info['query'])) {
parse_str($target_info['query'], $query_params);
}
$query_params = array_merge($query_params, $params);
$target_info['query'] = http_build_query($query_params);
$target = unparse_url($target_info);
} elseif ($config_item['type'] == 'call') {
$target = $config_item['target'];
}
$new_config_item = clone $config_item;
$new_config_item['target'] = $target;
$new_config_item['concurrency_id'] = $i;
$request_list[] = $new_config_item;
}
return $request_list;
}
public static function initConfigItem($config)
{
$default = [
'name' => 'http_demo',
'type' => 'site',
'target' => '',
'frequency' => 600,
'concurrency' => 1,
'run_type' => 'auto',
];
$data = array_merge($default, $config);
if ($data['frequency'] < 0) {
$data['frequency'] = 0;
}
$model_timer = new VirtualModel($data);
return $model_timer;
}
}