fix: prevent timer leaks and race conditions in config/profile/ssid modules

This commit is contained in:
xmk23333 2026-01-04 16:45:42 +08:00
parent 923bd8d7ee
commit 7b7333d271
3 changed files with 30 additions and 10 deletions

View File

@ -9,14 +9,16 @@ let appConfigWriteQueue: Promise<void> = Promise.resolve()
export async function getAppConfig(force = false): Promise<IAppConfig> { export async function getAppConfig(force = false): Promise<IAppConfig> {
if (force || !appConfig) { if (force || !appConfig) {
const data = await readFile(appConfigPath(), 'utf-8') appConfigWriteQueue = appConfigWriteQueue.then(async () => {
const parsedConfig = parse(data) const data = await readFile(appConfigPath(), 'utf-8')
const mergedConfig = deepMerge({ ...defaultConfig }, parsedConfig || {}) const parsedConfig = parse(data)
if (JSON.stringify(mergedConfig) !== JSON.stringify(parsedConfig)) { const mergedConfig = deepMerge({ ...defaultConfig }, parsedConfig || {})
await writeFile(appConfigPath(), stringify(mergedConfig)) if (JSON.stringify(mergedConfig) !== JSON.stringify(parsedConfig)) {
} await writeFile(appConfigPath(), stringify(mergedConfig))
}
appConfig = mergedConfig appConfig = mergedConfig
})
await appConfigWriteQueue
} }
if (typeof appConfig !== 'object') appConfig = defaultConfig if (typeof appConfig !== 'object') appConfig = defaultConfig
return appConfig return appConfig

View File

@ -3,6 +3,7 @@ import { Cron } from 'croner'
import { logger } from '../utils/logger' import { logger } from '../utils/logger'
const intervalPool: Record<string, Cron | NodeJS.Timeout> = {} const intervalPool: Record<string, Cron | NodeJS.Timeout> = {}
const delayedUpdatePool: Record<string, NodeJS.Timeout> = {}
async function updateProfile(id: string): Promise<void> { async function updateProfile(id: string): Promise<void> {
const item = await getProfileItem(id) const item = await getProfileItem(id)
@ -61,8 +62,9 @@ export async function initProfileUpdater(): Promise<void> {
currentItem.interval * 60 * 1000 currentItem.interval * 60 * 1000
) )
setTimeout( delayedUpdatePool[currentId] = setTimeout(
async () => { async () => {
delete delayedUpdatePool[currentId]
try { try {
await updateProfile(currentId) await updateProfile(currentId)
} catch (e) { } catch (e) {
@ -132,4 +134,8 @@ export async function removeProfileUpdater(id: string): Promise<void> {
} }
delete intervalPool[id] delete intervalPool[id]
} }
if (delayedUpdatePool[id]) {
clearTimeout(delayedUpdatePool[id])
delete delayedUpdatePool[id]
}
} }

View File

@ -32,6 +32,8 @@ export async function getCurrentSSID(): Promise<string | undefined> {
} }
let lastSSID: string | undefined let lastSSID: string | undefined
let ssidCheckInterval: NodeJS.Timeout | null = null
export async function checkSSID(): Promise<void> { export async function checkSSID(): Promise<void> {
try { try {
const { pauseSSID = [] } = await getAppConfig() const { pauseSSID = [] } = await getAppConfig()
@ -56,8 +58,18 @@ export async function checkSSID(): Promise<void> {
} }
export async function startSSIDCheck(): Promise<void> { export async function startSSIDCheck(): Promise<void> {
if (ssidCheckInterval) {
clearInterval(ssidCheckInterval)
}
await checkSSID() await checkSSID()
setInterval(checkSSID, 30000) ssidCheckInterval = setInterval(checkSSID, 30000)
}
export function stopSSIDCheck(): void {
if (ssidCheckInterval) {
clearInterval(ssidCheckInterval)
ssidCheckInterval = null
}
} }
async function getSSIDByAirport(): Promise<string | undefined> { async function getSSIDByAirport(): Promise<string | undefined> {