fix: watcher duplicated at each toggling of a plugin

Massimo Melina committed Apr 17, 2022 at 12:03 UTC 076cdf75e304c0b7b3ee13536ee5a47e4f508fd9
2 files changed +25 -14
server/src/misc.ts
+19 -7
@@ -117,14 +117,26 @@ export function onFirstEvent(emitter:EventEmitter, events: string[], cb: (...arg
117 }
118
119 export function watchDir(dir: string, cb: ()=>void) {
120 - const base = basename(dir)
121 - watch(dirname(dir), (event,name) => {
122 - if (name === base)
123 - cb()
124 - })
125 - cb()
120 try { watch(dir, cb) }
127 - catch {}
121 + catch {
122 + // failing watching the content of the dir, we try to monitor its parent, but filtering events only for our target dir
123 + const base = basename(dir)
124 + try {
125 + const watcher = watch(dirname(dir), (event,name) => {
126 + if (name !== base) return
127 + try {
128 + watch(dir, cb) // attempt at passing to a more specific watching
129 + watcher.close() // if we succeed, we give up the parent watching
130 + }
131 + catch {}
132 + cb()
133 + })
134 + }
135 + catch (e) {
136 + console.debug(String(e))
137 + return false
138 + }
139 + }
140 }
141
142 export function pattern2filter(pattern: string){
server/src/plugins.ts
+6 -7
@@ -14,6 +14,7 @@ import { VfsNode } from './vfs'
14 import { serveFile } from './serveFile'
15 import events from './events'
16 import { readFile } from 'fs/promises'
17 +import { existsSync, mkdirSync } from 'fs'
18
19 const PATH = 'plugins'
20
@@ -62,13 +63,6 @@ export function pluginsMiddleware(): Koa.Middleware {
63 }
64 }
65
65 -subscribeConfig({ k:'disable_plugins', defaultValue:['download-counter', 'redirect-root'] }, () => {
66 - try { watchDir(PATH, debounceAsync(rescan, 1000)) }
67 - catch {
68 - console.debug('plugins not found')
69 - }
70 -})
71 -
66 // return false to ask to exclude this entry from results
67 interface OnDirEntryParams { entry:DirEntry, ctx:Koa.Context, node:VfsNode }
68 type OnDirEntry = (params:OnDirEntryParams) => void | false
@@ -137,6 +131,11 @@ export function getAvailablePlugins() {
131 return Object.values(availablePlugins)
132 }
133
134 +const rescanAsap = debounceAsync(rescan, 1000)
135 +watchDir(PATH, rescanAsap)
136 +
137 +subscribeConfig({ k:'disable_plugins', defaultValue:['download-counter', 'redirect-root'] }, rescanAsap)
138 +
139 async function rescan() {
140 console.debug('scanning plugins')
141 const found = []