From 13e561c51a3c95b0bf3676d8a7ab983449a2f332 Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 27 Sep 2022 01:12:04 +0800 Subject: [PATCH] ui: optimize: debounced reload --- install/install.ts | 25 +++++++++++++++---------- packages/hydrooj/package.json | 3 ++- packages/hydrooj/src/loader.ts | 16 +++++++--------- packages/hydrooj/src/service/watcher.ts | 2 +- packages/ui-default/handler.ts | 14 +++++++------- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/install/install.ts b/install/install.ts index 97cc866e..10b83944 100644 --- a/install/install.ts +++ b/install/install.ts @@ -86,12 +86,12 @@ let migration; let retry = 0; log.info('install.start'); const defaultDict = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; -String.random = function random(digit = 32, dict = defaultDict) { +function randomstring(digit = 32, dict = defaultDict) { let str = ''; for (let i = 1; i <= digit; i++) str += dict[Math.floor(Math.random() * dict.length)]; return str; -}; -let DATABASE_PASSWORD = String.random(32); +} +let password = randomstring(32); // TODO read from args const CN = true; @@ -128,9 +128,14 @@ function removeOptionalEsbuildDeps() { data.resolutions = data.resolutions || {}; Object.assign(data.resolutions, Object.fromEntries([ '@esbuild/linux-loong64', - ...['android', 'windows', 'darwin', 'freebsd'].flatMap((i) => [`${i}-64`, `${i}-arm64`, `${i}-32`]), - ...['32', 'arm', 'mips64', 'ppc64', 'riscv64', 's390x'].map((i) => `esbuild-linux-${i}`), - ...['netbsd', 'openbsd', 'sunos'].map((i) => `esbuild-${i}-64`), + 'esbuild-windows-32', + ...['android', 'darwin', 'freebsd', 'windows'] + .flatMap((i) => [`${i}-64`, `${i}-arm64`]) + .map((i) => `esbuild-${i}`), + ...['32', 'arm', 'mips64', 'ppc64', 'riscv64', 's390x'] + .map((i) => `esbuild-linux-${i}`), + ...['netbsd', 'openbsd', 'sunos'] + .map((i) => `esbuild-${i}-64`), ].map((i) => [i, 'link:/dev/null']))); exec(`mkdir -p ${yarnGlobalPath}`); writeFileSync(pkgjson, JSON.stringify(data, null, 2)); @@ -195,7 +200,7 @@ const steps = [ () => sleep(3000), () => writeFileSync('/tmp/createUser.js', `db.createUser(${JSON.stringify({ user: 'hydro', - pwd: DATABASE_PASSWORD, + pwd: password, roles: [{ role: 'readWrite', db: 'hydro' }], })})`), ['mongo 127.0.0.1:27017/hydro /tmp/createUser.js', { retry: true }], @@ -204,7 +209,7 @@ const steps = [ port: 27017, name: 'hydro', username: 'hydro', - password: DATABASE_PASSWORD, + password, })), 'pm2 stop mongod', 'pm2 del mongod', @@ -250,10 +255,10 @@ const steps = [ init: 'install.done', operations: [ () => { - DATABASE_PASSWORD = require(`${process.env.HOME}/.hydro/config.json`).password; + password = require(`${process.env.HOME}/.hydro/config.json`).password; }, () => log.info('extra.dbUser'), - () => log.info('extra.dbPassword', DATABASE_PASSWORD), + () => log.info('extra.dbPassword', password), ], }, ]; diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index fd3d0eea..acd32fa4 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -49,7 +49,8 @@ "semver": "^7.3.7", "serialize-javascript": "^6.0.0", "superagent": "^8.0.0", - "thirty-two": "^1.0.2" + "thirty-two": "^1.0.2", + "ws": "^8.9.0" }, "devDependencies": { "@types/adm-zip": "^0.4.34", diff --git a/packages/hydrooj/src/loader.ts b/packages/hydrooj/src/loader.ts index 279ee74d..828cbaa8 100644 --- a/packages/hydrooj/src/loader.ts +++ b/packages/hydrooj/src/loader.ts @@ -38,8 +38,7 @@ export function resolveConfig(plugin: any, config: any) { Context.service('loader'); export class Loader { - static readonly kUpdate = Symbol.for('koishi.loader.update'); - static readonly kRecord = Symbol.for('koishi.loader.record'); + static readonly Record = Symbol.for('loader.record'); public app: Context; public config: Context.Config; @@ -47,19 +46,18 @@ export class Loader { public cache: Record = Object.create(null); unloadPlugin(ctx: Context, key: string) { - const fork = ctx.state[Loader.kRecord][key]; + const fork = ctx.state[Loader.Record][key]; if (fork) { fork.dispose(); - delete ctx.state[Loader.kRecord][key]; + delete ctx.state[Loader.Record][key]; logger.info('unload plugin %c', key); } } async reloadPlugin(parent: Context, key: string, config: any, asName = '') { - let fork = parent.state[Loader.kRecord]?.[key]; + let fork = parent.state[Loader.Record]?.[key]; if (fork) { logger.info('reload plugin %c', key); - fork[Loader.kUpdate] = true; fork.update(config); } else { logger.info('apply plugin %c', key); @@ -70,8 +68,8 @@ export class Loader { // fork = parent.plugin(plugin, this.interpolate(config)); fork = parent.plugin(plugin, config); if (!fork) return; - parent.state[Loader.kRecord] ||= Object.create(null); - parent.state[Loader.kRecord][key] = fork; + parent.state[Loader.Record] ||= Object.create(null); + parent.state[Loader.Record][key] = fork; } return fork; } @@ -121,7 +119,7 @@ Context.service('loader'); const loader = new Loader(); app.loader = loader; loader.app = app; -app.state[Loader.kRecord] = Object.create(null); +app.state[Loader.Record] = Object.create(null); export async function load() { addon(path.resolve(__dirname, '..'), true); diff --git a/packages/hydrooj/src/service/watcher.ts b/packages/hydrooj/src/service/watcher.ts index 283b8854..951550cb 100644 --- a/packages/hydrooj/src/service/watcher.ts +++ b/packages/hydrooj/src/service/watcher.ts @@ -49,7 +49,7 @@ export default class Watcher extends Service { if (process.env.WATCH_ROOT) roots.push(process.env.WATCH_ROOT); this.watcher = watch(roots, { ...this.config, - ignored: ['node_modules', '.git', 'logs', '.cache'] + ignored: ['node_modules', '.git', 'logs', '.cache', '.yarn'] .map((i) => `**/${i}/**`).concat('**/tsconfig.tsbuildinfo'), }); logger.info(`Start watching changes in ${this.root}`); diff --git a/packages/ui-default/handler.ts b/packages/ui-default/handler.ts index 046bcb27..1cf2755c 100644 --- a/packages/ui-default/handler.ts +++ b/packages/ui-default/handler.ts @@ -13,6 +13,7 @@ import user from 'hydrooj/src/model/user'; import { UiContextBase } from 'hydrooj/src/service/layers/base'; import { Handler } from 'hydrooj/src/service/server'; import { SystemSettings } from 'hydrooj/src/settings'; +import { debounce } from 'lodash'; import { ObjectID } from 'mongodb'; import { tmpdir } from 'os'; import { join, resolve } from 'path'; @@ -239,14 +240,13 @@ export function apply(ctx) { ctx.on('app/started', buildUI); ctx.on('app/started', updateLogo); ctx.on('system/setting', updateLogo); - ctx.on('app/watch/change', (path) => { + const debouncedBuildUI = debounce(buildUI, 1000); + const triggerHotUpdate = (path) => { if (!path.includes('/ui-default/') && !path.includes('/public/')) return; - buildUI(); - }); - ctx.on('app/watch/unlink', (path) => { - if (!path.includes('/ui-default/') && !path.includes('/public/')) return; - buildUI(); - }); + debouncedBuildUI(); + }; + ctx.on('app/watch/change', triggerHotUpdate); + ctx.on('app/watch/unlink', triggerHotUpdate); buildUI(); updateLogo(); }