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")
 | 
			
		||||
        this.pluginManager.disable(this.pluginManager.getPlugins())
 | 
			
		||||
        this.taskManager.disable()
 | 
			
		||||
        process.emit('exit', 0)
 | 
			
		||||
        process.exit(0)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,9 @@ class Process extends EventEmitter {
 | 
			
		||||
    queueMicrotask(func: Function) {
 | 
			
		||||
        microTaskPool.execute(func)
 | 
			
		||||
    }
 | 
			
		||||
    exit() {
 | 
			
		||||
        microTaskPool.shutdown();
 | 
			
		||||
    exit(code: number) {
 | 
			
		||||
        process.emit('exit', code)
 | 
			
		||||
        microTaskPool.shutdown()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
global.setGlobal('process', new Process(), {})
 | 
			
		||||
 
 | 
			
		||||
@@ -79,23 +79,16 @@ export function config(metadata: interfaces.ConfigMetadata = {}) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function stage(metadata: interfaces.ExecMetadata = {}, stage: string) {
 | 
			
		||||
    return function (target: any, key: string, value: any) {
 | 
			
		||||
        metadata.name = metadata.name || key
 | 
			
		||||
        metadata.executor = key
 | 
			
		||||
        const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
 | 
			
		||||
        Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor)
 | 
			
		||||
function stage(stage: string) {
 | 
			
		||||
    return (metadata: interfaces.ExecMetadata = {}) => {
 | 
			
		||||
        return function (target: any, key: string, value: any) {
 | 
			
		||||
            metadata.name = metadata.name || key
 | 
			
		||||
            metadata.executor = key
 | 
			
		||||
            const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
 | 
			
		||||
            Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function load(metadata: interfaces.ExecMetadata = {}) {
 | 
			
		||||
    return stage(metadata, 'load')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function enable(metadata: interfaces.ExecMetadata = {}) {
 | 
			
		||||
    return stage(metadata, 'enable')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function disable(metadata: interfaces.ExecMetadata = {}) {
 | 
			
		||||
    return stage(metadata, 'disable')
 | 
			
		||||
}
 | 
			
		||||
export const load = stage('load')
 | 
			
		||||
export const enable = stage('enable')
 | 
			
		||||
export const disable = stage('disable')
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,8 @@ export class BasicLoader implements plugin.PluginLoader {
 | 
			
		||||
        this.pluginRequireMap = new Map()
 | 
			
		||||
    }
 | 
			
		||||
    require(loadMetadata: plugin.PluginLoadMetadata) {
 | 
			
		||||
        let metadata = loadMetadata.instance.description
 | 
			
		||||
        if (metadata && metadata.type == this.type) {
 | 
			
		||||
        let metadata = loadMetadata.instance?.description
 | 
			
		||||
        if (metadata?.type == this.type) {
 | 
			
		||||
            loadMetadata.metadata = metadata
 | 
			
		||||
            loadMetadata.loaded = true
 | 
			
		||||
            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.initialized = true
 | 
			
		||||
            process.emit('plugin.initialize')
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -77,10 +78,12 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
                console.ex(error)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        process.emit('plugin.scan', folder)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    build(): void {
 | 
			
		||||
        this.buildPlugins()
 | 
			
		||||
        process.emit('plugin.build')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private logStage(plugin: plugin.Plugin, stage: string) {
 | 
			
		||||
@@ -101,14 +104,25 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 {
 | 
			
		||||
            for (const [, loader] of this.loaderMap) {
 | 
			
		||||
                if (loader.require(loadMetadata).loaded) {
 | 
			
		||||
                    loadMetadata.loader = loader
 | 
			
		||||
                    let metadata = loadMetadata.metadata
 | 
			
		||||
                    this.metadataMap.set(metadata.name, metadata)
 | 
			
		||||
                    metadata.loadMetadata = loadMetadata
 | 
			
		||||
                    return metadata
 | 
			
		||||
                try {
 | 
			
		||||
                    if (loader.require(loadMetadata).loaded) {
 | 
			
		||||
                        loadMetadata.loader = loader
 | 
			
		||||
                        let metadata = loadMetadata.metadata
 | 
			
		||||
                        this.metadataMap.set(metadata.name, metadata)
 | 
			
		||||
                        metadata.loadMetadata = loadMetadata
 | 
			
		||||
                        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) {
 | 
			
		||||
@@ -123,8 +137,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
     * @param file java.io.File
 | 
			
		||||
     */
 | 
			
		||||
    loadFromFile(file: string, scanner = this.sacnnerMap.get('file')): plugin.Plugin {
 | 
			
		||||
        if (!file) { throw new Error('plugin file can\'t be null!') }
 | 
			
		||||
        if (!scanner) { throw new Error('plugin scanner 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 undefiend!') }
 | 
			
		||||
        let metadata = this.loadPlugin(scanner.read(file))
 | 
			
		||||
        let plugin = metadata.loadMetadata.loader.build(metadata)
 | 
			
		||||
        this.load(plugin)
 | 
			
		||||
@@ -162,7 +176,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
    reload(...args: any[]): void {
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((pl: plugin.Plugin) => {
 | 
			
		||||
            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[] {
 | 
			
		||||
        if (name === undefined) throw new Error(`checkAndGet Plugin can't be undefiend!`)
 | 
			
		||||
        if (name == this.instanceMap) { return this.instanceMap }
 | 
			
		||||
        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.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!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ export class MySQLScanner implements plugin.PluginScanner {
 | 
			
		||||
    type: string = "mysql"
 | 
			
		||||
 | 
			
		||||
    private cacheDir = 'mysql-plugin-cache'
 | 
			
		||||
    private cacheFileMap: Map<string, MySQLPlugin> = new Map()
 | 
			
		||||
    private target: string
 | 
			
		||||
 | 
			
		||||
    @inject(database.DataBaseManager)
 | 
			
		||||
@@ -25,7 +26,14 @@ export class MySQLScanner implements plugin.PluginScanner {
 | 
			
		||||
        return plugins.map(p => this.read(p))
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
        if (metadata.type !== this.type) { return }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user