feat: optimize process & plugin loader and scanner
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
678f4ca8a4
commit
0bc513d580
@ -53,7 +53,6 @@ class MiaoScriptCore {
|
|||||||
console.i18n("ms.core.engine.disable")
|
console.i18n("ms.core.engine.disable")
|
||||||
this.pluginManager.disable(this.pluginManager.getPlugins())
|
this.pluginManager.disable(this.pluginManager.getPlugins())
|
||||||
this.taskManager.disable()
|
this.taskManager.disable()
|
||||||
process.emit('exit', 0)
|
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,9 @@ class Process extends EventEmitter {
|
|||||||
queueMicrotask(func: Function) {
|
queueMicrotask(func: Function) {
|
||||||
microTaskPool.execute(func)
|
microTaskPool.execute(func)
|
||||||
}
|
}
|
||||||
exit() {
|
exit(code: number) {
|
||||||
microTaskPool.shutdown();
|
process.emit('exit', code)
|
||||||
|
microTaskPool.shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global.setGlobal('process', new Process(), {})
|
global.setGlobal('process', new Process(), {})
|
||||||
|
@ -79,23 +79,16 @@ export function config(metadata: interfaces.ConfigMetadata = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stage(metadata: interfaces.ExecMetadata = {}, stage: string) {
|
function stage(stage: string) {
|
||||||
|
return (metadata: interfaces.ExecMetadata = {}) => {
|
||||||
return function (target: any, key: string, value: any) {
|
return function (target: any, key: string, value: any) {
|
||||||
metadata.name = metadata.name || key
|
metadata.name = metadata.name || key
|
||||||
metadata.executor = key
|
metadata.executor = key
|
||||||
const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
|
const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
|
||||||
Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor)
|
Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
export const load = stage('load')
|
||||||
export function load(metadata: interfaces.ExecMetadata = {}) {
|
export const enable = stage('enable')
|
||||||
return stage(metadata, 'load')
|
export const disable = stage('disable')
|
||||||
}
|
|
||||||
|
|
||||||
export function enable(metadata: interfaces.ExecMetadata = {}) {
|
|
||||||
return stage(metadata, 'enable')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function disable(metadata: interfaces.ExecMetadata = {}) {
|
|
||||||
return stage(metadata, 'disable')
|
|
||||||
}
|
|
||||||
|
@ -11,8 +11,8 @@ export class BasicLoader implements plugin.PluginLoader {
|
|||||||
this.pluginRequireMap = new Map()
|
this.pluginRequireMap = new Map()
|
||||||
}
|
}
|
||||||
require(loadMetadata: plugin.PluginLoadMetadata) {
|
require(loadMetadata: plugin.PluginLoadMetadata) {
|
||||||
let metadata = loadMetadata.instance.description
|
let metadata = loadMetadata.instance?.description
|
||||||
if (metadata && metadata.type == this.type) {
|
if (metadata?.type == this.type) {
|
||||||
loadMetadata.metadata = metadata
|
loadMetadata.metadata = metadata
|
||||||
loadMetadata.loaded = true
|
loadMetadata.loaded = true
|
||||||
this.pluginRequireMap.set(metadata.source.toString(), loadMetadata.instance)
|
this.pluginRequireMap.set(metadata.source.toString(), loadMetadata.instance)
|
||||||
|
@ -56,6 +56,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
this.loaderMap.set(loader.type, loader)
|
this.loaderMap.set(loader.type, loader)
|
||||||
})
|
})
|
||||||
this.initialized = true
|
this.initialized = true
|
||||||
|
process.emit('plugin.initialize')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,10 +78,12 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
console.ex(error)
|
console.ex(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
process.emit('plugin.scan', folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
build(): void {
|
build(): void {
|
||||||
this.buildPlugins()
|
this.buildPlugins()
|
||||||
|
process.emit('plugin.build')
|
||||||
}
|
}
|
||||||
|
|
||||||
private logStage(plugin: plugin.Plugin, stage: string) {
|
private logStage(plugin: plugin.Plugin, stage: string) {
|
||||||
@ -101,8 +104,11 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private loadPlugin(loadMetadata: plugin.PluginLoadMetadata) {
|
private loadPlugin(loadMetadata: plugin.PluginLoadMetadata) {
|
||||||
|
if (!loadMetadata) { throw new Error('loadMetadata can\'t be undefiend when loadPlugin!') }
|
||||||
|
if (loadMetadata.loaded) { throw new Error(`Plugin ${loadMetadata.name} is already loaded by ${loadMetadata.loader?.type}!`) }
|
||||||
try {
|
try {
|
||||||
for (const [, loader] of this.loaderMap) {
|
for (const [, loader] of this.loaderMap) {
|
||||||
|
try {
|
||||||
if (loader.require(loadMetadata).loaded) {
|
if (loader.require(loadMetadata).loaded) {
|
||||||
loadMetadata.loader = loader
|
loadMetadata.loader = loader
|
||||||
let metadata = loadMetadata.metadata
|
let metadata = loadMetadata.metadata
|
||||||
@ -110,6 +116,14 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
metadata.loadMetadata = loadMetadata
|
metadata.loadMetadata = loadMetadata
|
||||||
return metadata
|
return metadata
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (global.debug) {
|
||||||
|
console.console(`§6Loader §b${loader.type} §6load §a${loadMetadata.file} §cerror. §4Err: §c${error}`)
|
||||||
|
console.ex(error)
|
||||||
|
} else {
|
||||||
|
console.warn(`Loader ${loader.type} load ${loadMetadata.file} error. Err: ${error}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.i18n("ms.plugin.manager.initialize.error", { name: loadMetadata.file, ex: error })
|
console.i18n("ms.plugin.manager.initialize.error", { name: loadMetadata.file, ex: error })
|
||||||
@ -123,8 +137,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
* @param file java.io.File
|
* @param file java.io.File
|
||||||
*/
|
*/
|
||||||
loadFromFile(file: string, scanner = this.sacnnerMap.get('file')): plugin.Plugin {
|
loadFromFile(file: string, scanner = this.sacnnerMap.get('file')): plugin.Plugin {
|
||||||
if (!file) { throw new Error('plugin file can\'t be null!') }
|
if (!file) { throw new Error('plugin file can\'t be undefiend!') }
|
||||||
if (!scanner) { throw new Error('plugin scanner can\'t be null!') }
|
if (!scanner) { throw new Error('plugin scanner can\'t be undefiend!') }
|
||||||
let metadata = this.loadPlugin(scanner.read(file))
|
let metadata = this.loadPlugin(scanner.read(file))
|
||||||
let plugin = metadata.loadMetadata.loader.build(metadata)
|
let plugin = metadata.loadMetadata.loader.build(metadata)
|
||||||
this.load(plugin)
|
this.load(plugin)
|
||||||
@ -162,7 +176,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
reload(...args: any[]): void {
|
reload(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((pl: plugin.Plugin) => {
|
this.checkAndGet(args[0]).forEach((pl: plugin.Plugin) => {
|
||||||
this.disable(pl)
|
this.disable(pl)
|
||||||
this.loadFromFile(pl.description.source, pl.description.loadMetadata.scanner)
|
this.loadFromFile(pl.description.source.toString(), pl.description.loadMetadata.scanner)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,10 +198,11 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private checkAndGet(name: string | plugin.Plugin | undefined | any): Map<string, plugin.Plugin> | plugin.Plugin[] {
|
private checkAndGet(name: string | plugin.Plugin | undefined | any): Map<string, plugin.Plugin> | plugin.Plugin[] {
|
||||||
|
if (name === undefined) throw new Error(`checkAndGet Plugin can't be undefiend!`)
|
||||||
if (name == this.instanceMap) { return this.instanceMap }
|
if (name == this.instanceMap) { return this.instanceMap }
|
||||||
if (typeof name == 'string' && this.instanceMap.has(name)) { return [this.instanceMap.get(name)] }
|
if (typeof name == 'string' && this.instanceMap.has(name)) { return [this.instanceMap.get(name)] }
|
||||||
if (name instanceof interfaces.Plugin) { return [name as plugin.Plugin] }
|
if (name instanceof interfaces.Plugin) { return [name as plugin.Plugin] }
|
||||||
if (name.description || name.description.name) { return [name as plugin.Plugin] }
|
if (name.description?.name) { return [name as plugin.Plugin] }
|
||||||
throw new Error(`Plugin ${JSON.stringify(name)} not exist!`)
|
throw new Error(`Plugin ${JSON.stringify(name)} not exist!`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ export class MySQLScanner implements plugin.PluginScanner {
|
|||||||
type: string = "mysql"
|
type: string = "mysql"
|
||||||
|
|
||||||
private cacheDir = 'mysql-plugin-cache'
|
private cacheDir = 'mysql-plugin-cache'
|
||||||
|
private cacheFileMap: Map<string, MySQLPlugin> = new Map()
|
||||||
private target: string
|
private target: string
|
||||||
|
|
||||||
@inject(database.DataBaseManager)
|
@inject(database.DataBaseManager)
|
||||||
@ -25,7 +26,14 @@ export class MySQLScanner implements plugin.PluginScanner {
|
|||||||
return plugins.map(p => this.read(p))
|
return plugins.map(p => this.read(p))
|
||||||
}
|
}
|
||||||
read(mysqlPlugin: MySQLPlugin): plugin.PluginLoadMetadata {
|
read(mysqlPlugin: MySQLPlugin): plugin.PluginLoadMetadata {
|
||||||
return { name: mysqlPlugin.name, file: fs.concat(root, this.cacheDir, `${mysqlPlugin.name}.js`), type: this.type, mysqlPlugin, scanner: this }
|
// if invoke this function from loadFromFile mysqlPlugin is a string need read from cache
|
||||||
|
if (typeof mysqlPlugin == "string") {
|
||||||
|
if (!this.cacheFileMap.has(mysqlPlugin)) { throw new Error(`this file ${mysqlPlugin} is not read from mysql-scanner. can't reload from this scanner!`) }
|
||||||
|
mysqlPlugin = this.cacheFileMap.get(mysqlPlugin)
|
||||||
|
}
|
||||||
|
let cacheFile = fs.concat(root, this.cacheDir, `${mysqlPlugin.name}.js`)
|
||||||
|
this.cacheFileMap.set(cacheFile, mysqlPlugin)
|
||||||
|
return { name: mysqlPlugin.name, file: cacheFile, type: this.type, mysqlPlugin, scanner: this }
|
||||||
}
|
}
|
||||||
load(metadata: plugin.PluginLoadMetadata) {
|
load(metadata: plugin.PluginLoadMetadata) {
|
||||||
if (metadata.type !== this.type) { return }
|
if (metadata.type !== this.type) { return }
|
||||||
|
Loading…
Reference in New Issue
Block a user