mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-02-11 04:00:32 +08:00
fix: resolve race conditions in config writes and profile switching
This commit is contained in:
parent
8384953fb7
commit
2c639d5bff
@ -11,6 +11,7 @@ import { createLogger } from '../utils/logger'
|
|||||||
const controledMihomoLogger = createLogger('ControledMihomo')
|
const controledMihomoLogger = createLogger('ControledMihomo')
|
||||||
|
|
||||||
let controledMihomoConfig: Partial<IMihomoConfig> // mihomo.yaml
|
let controledMihomoConfig: Partial<IMihomoConfig> // mihomo.yaml
|
||||||
|
let controledMihomoWriteQueue: Promise<void> = Promise.resolve()
|
||||||
|
|
||||||
export async function getControledMihomoConfig(force = false): Promise<Partial<IMihomoConfig>> {
|
export async function getControledMihomoConfig(force = false): Promise<Partial<IMihomoConfig>> {
|
||||||
if (force || !controledMihomoConfig) {
|
if (force || !controledMihomoConfig) {
|
||||||
@ -39,6 +40,7 @@ export async function getControledMihomoConfig(force = false): Promise<Partial<I
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
|
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
|
||||||
|
controledMihomoWriteQueue = controledMihomoWriteQueue.then(async () => {
|
||||||
const { controlDns = true, controlSniff = true } = await getAppConfig()
|
const { controlDns = true, controlSniff = true } = await getAppConfig()
|
||||||
|
|
||||||
if (patch.hosts) {
|
if (patch.hosts) {
|
||||||
@ -64,4 +66,6 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
|
|||||||
|
|
||||||
await generateProfile()
|
await generateProfile()
|
||||||
await writeFile(controledMihomoConfigPath(), stringify(controledMihomoConfig), 'utf-8')
|
await writeFile(controledMihomoConfigPath(), stringify(controledMihomoConfig), 'utf-8')
|
||||||
|
})
|
||||||
|
await controledMihomoWriteQueue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ const profileLogger = createLogger('Profile')
|
|||||||
|
|
||||||
let profileConfig: IProfileConfig
|
let profileConfig: IProfileConfig
|
||||||
let profileConfigWriteQueue: Promise<void> = Promise.resolve()
|
let profileConfigWriteQueue: Promise<void> = Promise.resolve()
|
||||||
let targetProfileId: string | null = null
|
let changeProfileQueue: Promise<void> = Promise.resolve()
|
||||||
|
|
||||||
export async function getProfileConfig(force = false): Promise<IProfileConfig> {
|
export async function getProfileConfig(force = false): Promise<IProfileConfig> {
|
||||||
if (force || !profileConfig) {
|
if (force || !profileConfig) {
|
||||||
@ -63,37 +63,27 @@ export async function getProfileItem(id: string | undefined): Promise<IProfileIt
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function changeCurrentProfile(id: string): Promise<void> {
|
export async function changeCurrentProfile(id: string): Promise<void> {
|
||||||
|
// 使用队列确保 profile 切换串行执行,避免竞态条件
|
||||||
|
changeProfileQueue = changeProfileQueue.then(async () => {
|
||||||
const { current } = await getProfileConfig()
|
const { current } = await getProfileConfig()
|
||||||
|
if (current === id) return
|
||||||
if (current === id && targetProfileId !== id) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
targetProfileId = id
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateProfileConfig((config) => {
|
await updateProfileConfig((config) => {
|
||||||
config.current = id
|
config.current = id
|
||||||
return config
|
return config
|
||||||
})
|
})
|
||||||
|
|
||||||
if (targetProfileId !== id) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
await restartCore()
|
await restartCore()
|
||||||
if (targetProfileId === id) {
|
|
||||||
targetProfileId = null
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (targetProfileId === id) {
|
// 回滚配置
|
||||||
await updateProfileConfig((config) => {
|
await updateProfileConfig((config) => {
|
||||||
config.current = current
|
config.current = current
|
||||||
return config
|
return config
|
||||||
})
|
})
|
||||||
targetProfileId = null
|
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
await changeProfileQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateProfileItem(item: IProfileItem): Promise<void> {
|
export async function updateProfileItem(item: IProfileItem): Promise<void> {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { getAppConfig } from './config'
|
|||||||
import { quitWithoutCore, stopCore } from './core/manager'
|
import { quitWithoutCore, stopCore } from './core/manager'
|
||||||
import { triggerSysProxy } from './sys/sysproxy'
|
import { triggerSysProxy } from './sys/sysproxy'
|
||||||
import { hideDockIcon, showDockIcon } from './resolve/tray'
|
import { hideDockIcon, showDockIcon } from './resolve/tray'
|
||||||
import icon from '../resources/icon.png?asset'
|
import icon from '../../resources/icon.png?asset'
|
||||||
|
|
||||||
export let mainWindow: BrowserWindow | null = null
|
export let mainWindow: BrowserWindow | null = null
|
||||||
let quitTimeout: NodeJS.Timeout | null = null
|
let quitTimeout: NodeJS.Timeout | null = null
|
||||||
@ -78,7 +78,8 @@ function setupWindowEvents(
|
|||||||
scheduleQuitWithoutCore(autoQuitWithoutCoreDelay)
|
scheduleQuitWithoutCore(autoQuitWithoutCoreDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silentStart) {
|
// 开发模式下始终显示窗口
|
||||||
|
if (!silentStart || is.dev) {
|
||||||
clearQuitTimeout()
|
clearQuitTimeout()
|
||||||
window.show()
|
window.show()
|
||||||
window.focusOnWebView()
|
window.focusOnWebView()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user