From 731f3808ed1bf2d839b408a4ac43c66ad859885a Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 26 Dec 2021 13:08:28 +0100 Subject: refactor: Improved config reloading If we watch the containing directory, we can use inotify instead of stat polling. --- packages/main/src/index.ts | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'packages/main/src') diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index a79a6e2..605c17c 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts @@ -25,8 +25,13 @@ import { ipcMain, nativeTheme, } from 'electron'; -import { readFileSync, watchFile } from 'fs'; -import { readFile, stat, writeFile } from 'fs/promises'; +import { readFileSync } from 'fs'; +import { + readFile, + stat, + watch, + writeFile, +} from 'fs/promises'; import { autorun } from 'mobx'; import { applySnapshot, @@ -121,7 +126,9 @@ nativeTheme.on('updated', () => { store.setShouldUseDarkColors(nativeTheme.shouldUseDarkColors); }); -const configPath = join(app.getPath('userData'), 'config.json'); +const userDataDir = app.getPath('userData'); +const configFileName = 'config.json'; +const configPath = join(userDataDir, configFileName); let loadingConfig = false; let savingConfig = false; let configMtime: Date | null = null; @@ -175,21 +182,37 @@ onSnapshot(store.config, (snapshot) => { } }); -async function initializeConfig(): Promise { - await loadConfig(); - watchFile(configPath, ({ mtime }) => { +async function watchConfig(): Promise { + const configWatcher = watch(userDataDir, { + persistent: false, + }); + for await (const { eventType, filename } of configWatcher) { + if (eventType !== 'change' + && (filename !== configFileName || filename !== null)) { + continue; + } + let mtime: Date; + try { + const stats = await stat(configPath); + mtime = stats.mtime; + } catch (err) { + if ((err as NodeJS.ErrnoException).code === 'ENOENT') { + continue; + } + throw err; + } if (!savingConfig && (configMtime === null || mtime > configMtime)) { - loadConfig().catch((err) => { - console.error('Failed to reload config', configPath, err); - }); + await loadConfig(); configMtime = mtime; console.log('Reloaded config', configPath); } - }); + } } -initializeConfig().catch((err) => { +loadConfig().catch((err) => { console.error('Failed to load config', configPath, err); +}).then(watchConfig).catch((err) => { + console.error('Error when watching for config changes', configPath, err); }); const rendererBaseUrl = getResourceUrl('../renderer/'); -- cgit v1.2.3-54-g00ecf