feat: optimize process & plugin loader and scanner
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -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 }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user