sounder code: async functions should be debounced properly

Massimo Melina committed Feb 10, 2022 at 11:35 UTC 3708f834431a84c93fb92a010b8bb3c0c65dfc36
3 files changed +8 -9
src/config.ts
+3 -3
@@ -4,7 +4,7 @@ import { watchLoad } from './watchLoad'
4 import fs from 'fs/promises'
5 import yaml from 'yaml'
6 import _ from 'lodash'
7 -import { objSameKeys, onOffMap } from './misc'
7 +import { debounceAsync, objSameKeys, onOffMap } from './misc'
8 import { exists } from 'fs'
9 import { promisify } from 'util'
10
@@ -99,7 +99,7 @@ export function setConfig(newCfg: Record<string,any>, partial=false) {
99 }
100 }
101
102 -export const saveConfigAsap = _.debounce(async () => {
102 +export const saveConfigAsap = debounceAsync(async () => {
103 let txt = yaml.stringify(state)
104 if (txt.trim() === '{}') // most users wouldn't understand
105 if (await promisify(exists)(path)) // if a file exists then empty it, else don't bother creating it
@@ -108,7 +108,7 @@ export const saveConfigAsap = _.debounce(async () => {
108 return
109 fs.writeFile(path, txt)
110 .catch(err => console.error('Failed at saving config file, please ensure it is writable.', String(err)))
111 -}, 100)
111 +})
112
113 // async version of getConfig, allowing you to wait for config to be ready
114 export async function getConfigReady<T>(k: string, definition?: object) {
src/plugins.ts
+2 -2
@@ -4,7 +4,7 @@ import _ from 'lodash'
4 import { resolve } from 'path'
5 import { PLUGINS_PUB_URI } from './const'
6 import Koa from 'koa'
7 -import { getOrSet, onProcessExit, wantArray, watchDir } from './misc'
7 +import { debounceAsync, getOrSet, onProcessExit, wantArray, watchDir } from './misc'
8 import { getConfig, subscribeConfig } from './config'
9 import { DirEntry } from './api.file_list'
10 import { VfsNode } from './vfs'
@@ -58,7 +58,7 @@ export function pluginsMiddleware(): Koa.Middleware {
58 }
59
60 subscribeConfig({ k:'disable_plugins', defaultValue:[] }, () => {
61 - try { watchDir(PATH, _.debounce(rescan, 1000)) }
61 + try { watchDir(PATH, debounceAsync(rescan, 1000)) }
62 catch {
63 console.debug('plugins not found')
64 }
src/watchLoad.ts
+3 -4
@@ -1,7 +1,6 @@
1 import { FSWatcher, watch } from 'fs'
2 -import _ from 'lodash'
2 import yaml from 'yaml'
4 -import { readFileBusy } from './misc'
3 +import { debounceAsync, readFileBusy } from './misc'
4
5 export type WatchLoadCanceller = () => void
6
@@ -10,7 +9,7 @@ interface Options { failedOnFirstAttempt?: ()=>void }
9 export function watchLoad(path:string, parser:(data:any)=>void|Promise<void>, { failedOnFirstAttempt }:Options={}): WatchLoadCanceller {
10 let doing = false
11 let watcher: FSWatcher | undefined
13 - const debounced = _.debounce(load, 500)
12 + const debounced = debounceAsync(load, 500)
13 let retry: NodeJS.Timeout
14 init()
15 if (!watcher)
@@ -23,7 +22,7 @@ export function watchLoad(path:string, parser:(data:any)=>void|Promise<void>, {
22 function init() {
23 try {
24 watcher = watch(path, debounced)
26 - debounced() // if file is not accessible watch will throw and we won't get here
25 + debounced().then() // if file is not accessible watch will throw and we won't get here
26 }
27 catch {
28 retry = setTimeout(init, 1000) // manual watching until watch is successful