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> {
if (force || !appConfig) {
appConfigWriteQueue = appConfigWriteQueue.then(async () => {
const data = await readFile(appConfigPath(), 'utf-8')
const parsedConfig = parse(data)
const mergedConfig = deepMerge({ ...defaultConfig }, parsedConfig || {})
if (JSON.stringify(mergedConfig) !== JSON.stringify(parsedConfig)) {
await writeFile(appConfigPath(), stringify(mergedConfig))
}
appConfig = mergedConfig
})
await appConfigWriteQueue
}
if (typeof appConfig !== 'object') appConfig = defaultConfig
return appConfig

View File

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