|
| 1 | +import { type SystemConfig } from "@App/pkg/config/config"; |
| 2 | +import { type ScriptService } from "./script"; |
| 3 | +import { type SubscribeService } from "./subscribe"; |
| 4 | + |
| 5 | +// 如果距离下次检查还有超过30秒,则使用计算的时间;否则使用默认延迟 |
| 6 | +const MIN_REMAINING_TIME_MS = 30000; |
| 7 | +// Service Worker 启动后的默认延迟时间,给予足够的初始化时间 |
| 8 | +const DEFAULT_FIRST_CHECK_DELAY_MS = 6000; |
| 9 | +// 允许在预定时间前最多65秒内触发检查(考虑 alarm 触发时间的不精确性) |
| 10 | +const ALARM_TRIGGER_WINDOW_MS = 65000; |
| 11 | +// Service Worker 启动后允许执行 alarm 的延迟时间 |
| 12 | +const ALLOW_CHECK_DELAY_MS = 3000; |
| 13 | + |
| 14 | +export let allowRegularUpdateCheck = 0; // 避免SW启动时alarm触发 |
| 15 | + |
| 16 | +export const initRegularUpdateCheck = async (systemConfig: SystemConfig) => { |
| 17 | + // regularScriptUpdateCheck |
| 18 | + const [result, updateCycleSecond] = await Promise.all([ |
| 19 | + chrome.storage.local.get(["checkupdate_script_lasttime"]), |
| 20 | + systemConfig.getCheckScriptUpdateCycle(), // check_script_update_cycle |
| 21 | + ]); |
| 22 | + if (updateCycleSecond === 0) return; // no regular update check |
| 23 | + const now = Date.now(); |
| 24 | + let when = 0; |
| 25 | + const checkupdate_script_lasttime: number = result.checkupdate_script_lasttime || 0; |
| 26 | + // 有 checkupdate_script_lasttime 而且是单数值(上次的定时更新检查有完成) |
| 27 | + if (checkupdate_script_lasttime && (checkupdate_script_lasttime & 1) === 1) { |
| 28 | + const updateCycleMs = updateCycleSecond * 1000; |
| 29 | + const next = checkupdate_script_lasttime + updateCycleMs; |
| 30 | + if (next > now + MIN_REMAINING_TIME_MS) { |
| 31 | + when = next; |
| 32 | + } |
| 33 | + } |
| 34 | + when = when || now + DEFAULT_FIRST_CHECK_DELAY_MS; // 六秒后触发第一个alarm |
| 35 | + let targetPeriodInMinutes = Math.ceil(updateCycleSecond / 60); // 分钟 |
| 36 | + targetPeriodInMinutes = Math.ceil(targetPeriodInMinutes / 5) * 5; // 5的倍数 |
| 37 | + if (targetPeriodInMinutes < 15) targetPeriodInMinutes = 15; // 至少15分钟 |
| 38 | + chrome.alarms.create( |
| 39 | + "checkScriptUpdate", |
| 40 | + { |
| 41 | + when, |
| 42 | + periodInMinutes: targetPeriodInMinutes, |
| 43 | + }, |
| 44 | + () => { |
| 45 | + const lastError = chrome.runtime.lastError; |
| 46 | + if (lastError) { |
| 47 | + console.error("chrome.runtime.lastError in chrome.alarms.create:", lastError); |
| 48 | + // Starting in Chrome 117, the number of active alarms is limited to 500. Once this limit is reached, chrome.alarms.create() will fail. |
| 49 | + console.error("Chrome alarm is unable to create. Please check whether limit is reached."); |
| 50 | + } |
| 51 | + } |
| 52 | + ); |
| 53 | + allowRegularUpdateCheck = now + ALLOW_CHECK_DELAY_MS; // 可以触发alarm的更新程序了 |
| 54 | +}; |
| 55 | + |
| 56 | +const setCheckupdateScriptLasttime = async (t: number) => { |
| 57 | + try { |
| 58 | + // 试一下储存。储存不了也没所谓 |
| 59 | + await chrome.storage.local.set({ checkupdate_script_lasttime: t }); |
| 60 | + } catch (e: any) { |
| 61 | + console.error(e); |
| 62 | + } |
| 63 | +}; |
| 64 | + |
| 65 | +export const onRegularUpdateCheckAlarm = async ( |
| 66 | + systemConfig: SystemConfig, |
| 67 | + script: ScriptService, |
| 68 | + subscribe?: SubscribeService |
| 69 | +) => { |
| 70 | + const now = Date.now(); |
| 71 | + if (!allowRegularUpdateCheck || now < allowRegularUpdateCheck) return null; // 避免SW启动时alarm触发 |
| 72 | + const [result, updateCycleSecond] = await Promise.all([ |
| 73 | + chrome.storage.local.get(["checkupdate_script_lasttime"]), |
| 74 | + systemConfig.getCheckScriptUpdateCycle(), // check_script_update_cycle |
| 75 | + ]); |
| 76 | + if (updateCycleSecond === 0) return null; // no regular update check |
| 77 | + const checkupdate_script_lasttime: number = result.checkupdate_script_lasttime || 0; |
| 78 | + const targetWhen = checkupdate_script_lasttime + updateCycleSecond * 1000; |
| 79 | + if (targetWhen - ALARM_TRIGGER_WINDOW_MS > now) return null; // 已检查过了(alarm触发了) |
| 80 | + const storeTime = Math.floor(now / 2) * 2; // 双数 |
| 81 | + await setCheckupdateScriptLasttime(storeTime); // 双数值:alarm触发了,但不知道有没有真的检查好(例如中途浏览器关了) |
| 82 | + const res = await script.checkScriptUpdate({ checkType: "system" }); |
| 83 | + try { |
| 84 | + if (subscribe) { |
| 85 | + // 不论 checkScriptUpdate 成功与否,执行 checkSubscribeUpdate |
| 86 | + const checkDisableScript = await systemConfig.getUpdateDisableScript(); |
| 87 | + await subscribe.checkSubscribeUpdate(updateCycleSecond, checkDisableScript); |
| 88 | + } |
| 89 | + } catch (e: any) { |
| 90 | + console.error(e); |
| 91 | + } |
| 92 | + await setCheckupdateScriptLasttime(storeTime + 1); // 单数值:alarm触发了,而且真的检查好 |
| 93 | + return res; |
| 94 | +}; |
0 commit comments