refactor: 移除 restartGateway,openclaw.json 单次写入

gateway 自动检测文件变更并重启,clawd 无需主动 kill。
同时去掉 applyFullProviderFromVps 的预清理写盘,
改为拉完模型后一次性写入,避免 gateway 读到中间状态。

Made-with: Cursor
This commit is contained in:
stswangzhiping
2026-04-05 09:12:57 +08:00
parent 4852ded7e5
commit f6afcd5cc2

View File

@@ -4,7 +4,6 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const http = require('http'); const http = require('http');
const https = require('https'); const https = require('https');
const { exec } = require('child_process');
const log = require('./logger'); const log = require('./logger');
const { resolveOpenclawConfigFile } = require('./frpc'); const { resolveOpenclawConfigFile } = require('./frpc');
@@ -14,23 +13,6 @@ const FETCH_TIMEOUT_MS = 10_000;
/** 拉模型 + 写盘单次飞行:进行中则忽略新的 apply/remove */ /** 拉模型 + 写盘单次飞行:进行中则忽略新的 apply/remove */
let _busy = false; let _busy = false;
/**
* 终止 openclaw-gateway 进程,由 systemd --user 自动重新拉起以读取新配置。
* 每次写盘 openclaw.json 成功后应调用一次。
* 使用异步 exec不阻塞 Node.js 事件循环,避免干扰 LED / VFD 等后续操作。
*/
function restartGateway() {
exec('pkill -9 -x openclaw-gateway', (err) => {
if (err && err.code !== 1) {
log.warn('openclaw-provider', `restartGateway: ${err.message}`);
} else if (!err) {
log.info('openclaw-provider', 'openclaw-gateway 已终止,等待自动重启');
} else {
log.info('openclaw-provider', 'openclaw-gateway 进程不存在,无需终止');
}
});
}
function buildModelsUrl(baseUrl) { function buildModelsUrl(baseUrl) {
let u = String(baseUrl || '').trim().replace(/\/+$/, ''); let u = String(baseUrl || '').trim().replace(/\/+$/, '');
if (!/\/v1$/.test(u)) u = `${u}/v1`; if (!/\/v1$/.test(u)) u = `${u}/v1`;
@@ -103,6 +85,7 @@ function writeJsonFile(filePath, obj) {
/** /**
* 同步:从 openclaw.json 删除指定 provider解绑 * 同步:从 openclaw.json 删除指定 provider解绑
* 若 primary 指向该 provider先置为空串。 * 若 primary 指向该 provider先置为空串。
* gateway 检测到文件变更后会自动重启,无需 clawd 主动 kill。
*/ */
function removeProviderByName(providerId) { function removeProviderByName(providerId) {
if (_busy) { if (_busy) {
@@ -143,7 +126,6 @@ function removeProviderByName(providerId) {
writeJsonFile(configFile, config); writeJsonFile(configFile, config);
log.info('openclaw-provider', `provider 已移除: ${providerId}`); log.info('openclaw-provider', `provider 已移除: ${providerId}`);
restartGateway();
} }
function removeProviderFromConfig(config, providerId) { function removeProviderFromConfig(config, providerId) {
@@ -209,7 +191,8 @@ function addProviderSync(configFile, providerId, baseUrl, apiKey, models, defaul
} }
/** /**
* VPS 绑定:先同步删掉同名 provider再异步拉模型回调内同步 add。完成后执行 onDone如更新 origin * VPS 绑定:异步拉模型后一次性写入 openclaw.json
* gateway 检测到文件变更后会自动重启,无需 clawd 主动 kill。
*/ */
function applyFullProviderFromVps(provider, onDone) { function applyFullProviderFromVps(provider, onDone) {
if (_busy) { if (_busy) {
@@ -233,15 +216,6 @@ function applyFullProviderFromVps(provider, onDone) {
} }
_busy = true; _busy = true;
try {
const cfg = readJsonFile(configFile);
removeProviderFromConfig(cfg, name);
writeJsonFile(configFile, cfg);
} catch (e) {
log.warn('openclaw-provider', `apply 预清理失败: ${e.message}`);
_busy = false;
return;
}
fetchModels(baseUrl, apiKey, (err, models) => { fetchModels(baseUrl, apiKey, (err, models) => {
try { try {
@@ -257,7 +231,6 @@ function applyFullProviderFromVps(provider, onDone) {
log.warn('openclaw-provider', `onDone: ${e.message}`); log.warn('openclaw-provider', `onDone: ${e.message}`);
} }
} }
restartGateway();
} catch (e) { } catch (e) {
log.error('openclaw-provider', `apply 写配置失败: ${e.message}`); log.error('openclaw-provider', `apply 写配置失败: ${e.message}`);
} finally { } finally {