Skip to content

Commit

Permalink
feat(cli): support service diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jan 23, 2022
1 parent 26efdd2 commit f248736
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
24 changes: 24 additions & 0 deletions packages/cli/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,28 @@ export class Loader {
const plugin = this.resolvePlugin(name)
if (!plugin) return

const names = Object.keys(this.cache).filter((name) => {
const plugin = this.resolvePlugin(name)
const state = this.app.registry.get(plugin)
return state?.using.every(key => this.app[key])
})

const state = this.app.dispose(plugin)
if (state) logger.info(`dispose plugin %c`, name)

for (const name of names) {
this.diagnose(name)
}
}

reloadPlugin(name: string) {
const plugin = this.resolvePlugin(name)
if (!plugin) return

if (this.app.isActive) {
this.app._tasks.flush().then(() => this.diagnose(name))
}

const state = this.app.dispose(plugin)
const config = this.config.plugins[name]
logger.info(`%s plugin %c`, state ? 'reload' : 'apply', name)
Expand All @@ -144,4 +158,14 @@ export class Loader {
}
return app
}

diagnose(name: string) {
const plugin = this.resolvePlugin(name)
const state = this.app.registry.get(plugin)
if (!state) return

let missing = state.using.filter(key => !this.app[key])
if (!missing.length) return
this.app.logger('diagnostic').warn('plugin %c is missing required service %c', name, missing.join(', '))
}
}
6 changes: 5 additions & 1 deletion packages/cli/src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ addons.prepare(config)
const app = loader.createApp()

app.plugin(addons, app.options)
app.start()
app.start().then(() => {
for (const name in loader.cache) {
loader.diagnose(name)
}
})
11 changes: 6 additions & 5 deletions packages/core/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ export class App extends Context {
this.isActive = true
logger.debug('started')
for (const callback of this.getHooks('ready')) {
this._tasks.execute(callback)
this._tasks.queue(callback())
}
await this._tasks.tillIdle()
delete this._hooks.ready
await this._tasks.flush()
}

async stop() {
Expand Down Expand Up @@ -285,14 +286,14 @@ export namespace App {
class TaskQueue {
#internal = new Set<Promise<void>>()

execute(callback: () => any) {
const task = Promise.resolve(callback())
queue(value: any) {
const task = Promise.resolve(value)
.catch(err => logger.warn(err))
.then(() => this.#internal.delete(task))
this.#internal.add(task)
}

async tillIdle() {
async flush() {
while (this.#internal.size) {
await Promise.all(Array.from(this.#internal))
}
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Logger, makeArray, remove, Random, Promisify, Awaitable, Dict, MaybeArray, defineProperty } from '@koishijs/utils'
import { Logger, makeArray, remove, sleep, Random, Promisify, Awaitable, Dict, MaybeArray, defineProperty } from '@koishijs/utils'
import { Command } from './command'
import { Session } from './session'
import { User, Channel, Modules } from './database'
Expand Down Expand Up @@ -413,7 +413,7 @@ export class Context {

// handle special events
if (name === 'ready' && this.app.isActive) {
this.app._tasks.execute(listener)
this.app._tasks.queue(sleep(0).then(() => listener()))
return () => false
} else if (name === 'dispose') {
this.state.disposables[method](listener)
Expand Down
12 changes: 2 additions & 10 deletions plugins/frontend/console/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,11 @@ declare module 'koishi' {
}
}

export abstract class DataSource<T = any> {
protected start(): Awaitable<void> {}
protected stop(): Awaitable<void> {}
export abstract class DataSource<T = any> extends Service {
protected abstract get(forced?: boolean): Promise<T>

constructor(protected ctx: Context, protected name: keyof Sources) {
Context.service(`console.${name}`)
ctx.console.services[name] = this as never

sleep(0).then(() => {
ctx.on('ready', () => this.start())
ctx.on('dispose', () => this.stop())
})
super(ctx, `console.${name}`, true)
}

protected broadcast(type: string, value: any) {
Expand Down

0 comments on commit f248736

Please sign in to comment.