refactor(core): core task function

move event loop task to @ccms/micro-task thread

BREAKING CHANGE: setTimeout & setInterval no longer run on main thread

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
MiaoWoo 2020-11-18 16:32:09 +08:00
parent c5fac44362
commit 4bb2337f39
2 changed files with 46 additions and 18 deletions

View File

@ -1,25 +1,23 @@
let containerStartTime = Date.now() let containerStartTime = Date.now()
console.i18n("ms.core.ioc.initialize", { scope: global.scope }) console.i18n("ms.core.ioc.initialize", { scope: global.scope })
import { plugin, server, task, constants } from '@ccms/api' import { plugin, server, task, constants } from '@ccms/api'
import { DefaultContainer as container, inject, provideSingleton, ContainerInstance, buildProviderModule } from '@ccms/container' import { DefaultContainer as container, inject, provideSingleton, ContainerInstance, buildProviderModule, Autowired } from '@ccms/container'
console.i18n("ms.core.ioc.completed", { scope: global.scope, time: (Date.now() - containerStartTime) / 1000 }) console.i18n("ms.core.ioc.completed", { scope: global.scope, time: (Date.now() - containerStartTime) / 1000 })
import http from '@ccms/common/dist/http' import http from '@ccms/common/dist/http'
@provideSingleton(MiaoScriptCore) @provideSingleton(MiaoScriptCore)
class MiaoScriptCore { class MiaoScriptCore {
@inject(server.Console) @Autowired(server.Console)
private Console: Console private Console: Console
@inject(task.TaskManager) @Autowired(plugin.PluginFolder)
private taskManager: task.TaskManager
@inject(plugin.PluginFolder)
private pluginFolder: string private pluginFolder: string
@inject(plugin.PluginManager) @Autowired()
private taskManager: task.TaskManager
@Autowired()
private pluginManager: plugin.PluginManager private pluginManager: plugin.PluginManager
enable() { enable() {
this.loadServerConsole() this.loadServerConsole()
this.loadTaskFunction()
global.level = "TRACE"
this.loadPlugins() this.loadPlugins()
return () => this.disable() return () => this.disable()
} }
@ -29,15 +27,6 @@ class MiaoScriptCore {
global.setGlobal('console', new this.Console(), { writable: false, configurable: false }) global.setGlobal('console', new this.Console(), { writable: false, configurable: false })
} }
loadTaskFunction() {
global.setGlobal('setTimeout', (func: Function, tick: number, ...args: any[]) => {
return this.taskManager.create(func).later(tick).submit(...args)
}, { writable: false, configurable: false })
global.setGlobal('setInterval', (func: Function, tick: number, ...args: any[]) => {
return this.taskManager.create(func).timer(tick).submit(...args)
}, { writable: false, configurable: false })
}
loadPlugins() { loadPlugins() {
let loadPluginStartTime = new Date().getTime() let loadPluginStartTime = new Date().getTime()
console.i18n("ms.core.plugin.initialize") console.i18n("ms.core.plugin.initialize")

View File

@ -5,6 +5,7 @@ const ThreadGroup = Java.type("java.lang.ThreadGroup")
const AtomicInteger = Java.type("java.util.concurrent.atomic.AtomicInteger") const AtomicInteger = Java.type("java.util.concurrent.atomic.AtomicInteger")
const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor') const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor')
const LinkedBlockingQueue = Java.type("java.util.concurrent.LinkedBlockingQueue") const LinkedBlockingQueue = Java.type("java.util.concurrent.LinkedBlockingQueue")
const TimeUnit = Java.type("java.util.concurrent.TimeUnit")
const threadCount = new AtomicInteger(0) const threadCount = new AtomicInteger(0)
const threadGroup = new ThreadGroup("@ccms/ployfill-micro-task") const threadGroup = new ThreadGroup("@ccms/ployfill-micro-task")
@ -14,7 +15,6 @@ const microTaskPool = new ThreadPoolExecutor(
(run: any) => new Thread(threadGroup, run, "@ccms/micro-task-" + threadCount.incrementAndGet()), (run: any) => new Thread(threadGroup, run, "@ccms/micro-task-" + threadCount.incrementAndGet()),
new ThreadPoolExecutor.CallerRunsPolicy() new ThreadPoolExecutor.CallerRunsPolicy()
) )
class Process extends EventEmitter { class Process extends EventEmitter {
env = { env = {
__noSuchProperty__: (prop) => { __noSuchProperty__: (prop) => {
@ -44,7 +44,46 @@ class Process extends EventEmitter {
exit(code: number) { exit(code: number) {
process.emit('exit', code) process.emit('exit', code)
microTaskPool.shutdown() microTaskPool.shutdown()
console.log('await microTaskPool termination...')
microTaskPool.awaitTermination(5000, TimeUnit.MILLISECONDS)
} }
} }
const timeoutCount = new AtomicInteger(0)
const timeoutTasks = []
function setTimeout(func: Function, time: number, ...args: any[]) {
let taskId = timeoutCount.incrementAndGet()
timeoutTasks[taskId] = func
process.nextTick(() => {
Thread.sleep(time)
if (timeoutTasks[taskId]) { func(...args) }
})
return taskId
}
function clearTimeout(taskId: number) {
delete timeoutTasks[taskId]
}
const intervalCount = new AtomicInteger(0)
const intervalTasks = []
function setInterval(func: Function, time: number, ...args: any[]) {
let taskId = intervalCount.incrementAndGet()
intervalTasks[taskId] = func
process.nextTick(() => {
Thread.sleep(time)
while (intervalTasks[taskId]) {
func(...args)
Thread.sleep(time)
}
})
return taskId
}
function clearInterval(taskId: number) {
delete intervalTasks[taskId]
}
global.setGlobal('process', new Process(), {}) global.setGlobal('process', new Process(), {})
global.setGlobal('queueMicrotask', (func: any) => microTaskPool.execute(func), {}) global.setGlobal('queueMicrotask', (func: any) => microTaskPool.execute(func), {})
global.setGlobal('setTimeout', setTimeout, {})
global.setGlobal('clearTimeout', clearTimeout, {})
global.setGlobal('setImmediate', (func: Function, ...args: any[]) => setTimeout(func, 0, ...args), {})
global.setGlobal('clearImmediate ', clearTimeout, {})
global.setGlobal('setInterval', setInterval, {})
global.setGlobal('clearInterval', clearInterval, {})