mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 15:32:48 +08:00
Add execute() wrapper in TimerControllerBase that wraps do() with logStart/logEnd, captures return value to result field. Change site URL routing from /do to /execute with task_name injection. Add result field to system_timer_log scheme. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
173 lines
5.4 KiB
PHP
173 lines
5.4 KiB
PHP
<?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(),
|
||
'task_name' => $config_item['name'],
|
||
];
|
||
// 处理target
|
||
if ($config_item['type'] == 'site') {
|
||
$target_info = parse_url($target);
|
||
// 将 /do 替换为 /execute,用于日志包裹
|
||
if (isset($target_info['path'])) {
|
||
$target_info['path'] = preg_replace('#/do$#', '/execute', $target_info['path']);
|
||
}
|
||
$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;
|
||
}
|
||
}
|