handle "busy" error while reloading config files
Massimo Melina committed
Dec 20, 2021 at 13:25 UTC
340cffc46ce6afedf0c1d8d511ea8d8733484103
4 files changed
+20
-9
dev-notes.md
-1
@@ -1,5 +1,4 @@
1
# To do
2
-- when reloading vfs wait for it to be unlocked
2
- sticky breadcrumbs
3
- filter list
4
- search
src/misc.ts
+15
-2
@@ -1,4 +1,4 @@
1
-import { stat } from 'fs/promises'
1
+import fs from 'fs/promises'
2
import glob from 'fast-glob'
3
import { objSameKeys } from './obj'
4
@@ -11,7 +11,7 @@ export function wantArray(x:any) {
11
}
12
13
export async function isDirectory(path: string) {
14
- try { return (await stat(path)).isDirectory() }
14
+ try { return (await fs.stat(path)).isDirectory() }
15
catch(e) { return false }
16
}
17
@@ -26,3 +26,16 @@ export function prefix(pre:string, v:string|number, post:string='') {
26
export function setHidden(dest: object, src:object) {
27
Object.defineProperties(dest, objSameKeys(src, value => ({ enumerable:false, value })))
28
}
29
+
30
+export function wait(ms: number) {
31
+ return new Promise(res=> setTimeout(res,ms))
32
+}
33
+
34
+export async function readFileBusy(path: string): Promise<string> {
35
+ return fs.readFile(path, 'utf8').catch(e => {
36
+ if ((e as any)?.code !== 'EBUSY')
37
+ throw e
38
+ console.debug('busy')
39
+ return wait(100).then(()=> readFileBusy(path))
40
+ })
41
+}
src/perm.ts
+3
-4
@@ -4,7 +4,7 @@ import _ from 'lodash'
4
import yaml from 'yaml'
5
import { hashPassword, verifyPassword } from './crypt'
6
import { argv } from './const'
7
-import { setHidden } from './misc'
7
+import { readFileBusy, setHidden } from './misc'
8
import { SESSION_COOKIE } from './apis'
9
import { sessions } from './sessions'
10
import Koa from 'koa'
@@ -39,15 +39,14 @@ async function load() {
39
doing = true
40
try {
41
console.debug('loading', PATH)
42
- let file
42
+ let res
43
try {
44
- file = await fs.readFile(PATH, 'utf8')
44
+ res = yaml.parse(await readFileBusy(PATH))
45
}
46
catch(e){
47
console.warn('cannot read', PATH, e)
48
return
49
}
50
- const res = yaml.parse(file)
50
// we should validate content here
51
if (!res?.accounts)
52
return accounts = {}
src/vfs.ts
+2
-2
@@ -4,7 +4,7 @@ import fs from 'fs/promises'
4
import { FSWatcher, watch } from 'fs'
5
import { dirname, basename } from 'path'
6
import { isMatch } from 'micromatch'
7
-import { complySlashes, prefix } from './misc'
7
+import { complySlashes, prefix, readFileBusy } from './misc'
8
import { getCurrentUser } from './perm'
9
import Koa from 'koa'
10
@@ -49,7 +49,7 @@ export class Vfs {
49
async load(path: string, watchFile:boolean=true) {
50
console.debug('loading',path)
51
try {
52
- const data = await fs.readFile(path, 'utf8')
52
+ const data = await readFileBusy(path)
53
this.root = yaml.parse(data)
54
// we should validate content now
55
}