feat: decouple OTA updates into dedicated fast endpoints to avoid db timeouts

This commit is contained in:
2026-07-11 12:22:48 +08:00
parent bd6ef05722
commit 79ae234232
4 changed files with 26 additions and 12 deletions
+6 -2
View File
@@ -100,8 +100,12 @@ end
local function checkAndApplyUpdate() local function checkAndApplyUpdate()
if type(CFG) ~= 'table' then return end local serverBase = guessBaseFromStatusURL(serverURL)
local remoteTs = tonumber(CFG.update_counter) if #serverBase == 0 then return end
local url = serverBase:gsub("/+$", "") .. "/api/check-update?_t=" .. tostring(nowMs() + math.random(1, 999999))
local ok, data = getJSON(url)
if not ok or not data or not data.update_counter then return end
local remoteTs = tonumber(data.update_counter)
if not remoteTs or remoteTs <= 0 then return end if not remoteTs or remoteTs <= 0 then return end
+13 -3
View File
@@ -151,6 +151,18 @@ const resolveCurrentStationCode = (body, resolveStation) => {
return codes[0] || direct || fallback || ''; return codes[0] || direct || fallback || '';
}; };
// Dedicated lightweight OTA update endpoints
let globalUpdateCounter = Date.now();
router.post('/trigger-update', (req, res) => {
globalUpdateCounter++;
res.json({ ok: true, update_counter: globalUpdateCounter });
});
router.get('/check-update', (req, res) => {
res.json({ update_counter: globalUpdateCounter });
});
// Config // Config
router.get('/config', (req, res) => { router.get('/config', (req, res) => {
const cfg = DataService.getConfig(); const cfg = DataService.getConfig();
@@ -190,9 +202,7 @@ router.put('/config', async (req, res) => {
if (typeof incoming.force_update === 'boolean') { if (typeof incoming.force_update === 'boolean') {
cfg.force_update = incoming.force_update; cfg.force_update = incoming.force_update;
} }
if (incoming.update_counter) { // remove unused update_counter
cfg.update_counter = incoming.update_counter;
}
await DataService.saveConfig(cfg); await DataService.saveConfig(cfg);
appendReqLog(req, { category: 'admin', type: 'update_config_generic', detail: incoming }); appendReqLog(req, { category: 'admin', type: 'update_config_generic', detail: incoming });
io.emit('config:updated', cfg); io.emit('config:updated', cfg);
+5 -2
View File
@@ -690,8 +690,11 @@ local function drawVersionIndicator()
end end
local function checkAndApplyUpdate() local function checkAndApplyUpdate()
if type(CFG) ~= 'table' then return end local txt = fetchHTTP(API_BASE .. '/check-update?_t=' .. tostring(os.epoch and os.epoch("utc") or math.random(1, 999999)))
local remoteTs = tonumber(CFG.update_counter) if not txt then return end
local data = jsonDecode(txt)
if not data or not data.update_counter then return end
local remoteTs = tonumber(data.update_counter)
if not remoteTs or remoteTs <= 0 then return end if not remoteTs or remoteTs <= 0 then return end
+2 -5
View File
@@ -1483,12 +1483,9 @@ createApp({
isPushingUpdate.value = true; isPushingUpdate.value = true;
// 每次点击,更新计数器 +1,终端只要看到计数器变大就会更新
config.update_counter = (config.update_counter || 0) + 1;
config.force_update = true;
try { try {
await requestJson('/api/config', { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(config) }, { expectOk: true }); // 直接请求专门的轻量级触发更新接口,避免和庞大的配置文件保存混在一起导致超时
await requestJson('/api/trigger-update', { method: 'POST' }, { expectOk: true });
alert('推送指令发送完毕,终端将陆续更新'); alert('推送指令发送完毕,终端将陆续更新');
} catch (err) { } catch (err) {
console.error(err); console.error(err);