88
packages/spring/src/task.ts
Normal file
88
packages/spring/src/task.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { task, plugin } from '@ccms/api'
|
||||
import { inject, provideSingleton } from '@ccms/container'
|
||||
|
||||
const AtomicBoolean = Java.type("java.util.concurrent.atomic.AtomicBoolean")
|
||||
const Thread = Java.type('java.lang.Thread')
|
||||
const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor')
|
||||
const ThreadPoolTaskExecutor = Java.type('org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor')
|
||||
|
||||
let executor: any
|
||||
let tasks: { [key: number]: task.Cancelable } = {}
|
||||
let taskId = 0
|
||||
|
||||
@provideSingleton(task.TaskManager)
|
||||
export class SpringTaskManager implements task.TaskManager {
|
||||
@inject(plugin.PluginInstance)
|
||||
private pluginInstance: any
|
||||
|
||||
constructor() {
|
||||
executor = new ThreadPoolTaskExecutor()
|
||||
executor.setCorePoolSize(10)
|
||||
executor.setMaxPoolSize(100)
|
||||
executor.setQueueCapacity(500)
|
||||
executor.setKeepAliveSeconds(60)
|
||||
executor.setThreadNamePrefix("@ccms/spring-")
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())
|
||||
executor.initialize()
|
||||
}
|
||||
|
||||
create(func: Function): task.Task {
|
||||
if (Object.prototype.toString.call(func) !== "[object Function]") { throw TypeError('第一个参数 Task 必须为 function !') }
|
||||
return new SpringTask(this.pluginInstance, func)
|
||||
}
|
||||
callSyncMethod(func: Function): any {
|
||||
return func()
|
||||
}
|
||||
disable() {
|
||||
Object.values(tasks).forEach((task) => task.cancel())
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
export class SpringTask extends task.Task {
|
||||
public id = taskId++
|
||||
private running = new AtomicBoolean(true)
|
||||
|
||||
run() {
|
||||
if (this.laterTime > 0) {
|
||||
try {
|
||||
Thread.sleep(this.laterTime)
|
||||
} catch (ex) {
|
||||
Thread.currentThread().interrupt()
|
||||
}
|
||||
}
|
||||
while (this.running.get()) {
|
||||
try {
|
||||
this.func()
|
||||
} catch (t) {
|
||||
console.error("Task exec error:", t)
|
||||
console.ex(t)
|
||||
}
|
||||
// If we have a interval of 0 or less, only run once
|
||||
if (this.interval <= 0) { break }
|
||||
try {
|
||||
Thread.sleep(this.interval)
|
||||
} catch (ex) {
|
||||
Thread.currentThread().interrupt()
|
||||
}
|
||||
}
|
||||
this.cancel()
|
||||
}
|
||||
|
||||
cancel(): any {
|
||||
var wasRunning = this.running.getAndSet(false)
|
||||
if (wasRunning) {
|
||||
tasks[this.id] = undefined
|
||||
}
|
||||
}
|
||||
|
||||
submit(): task.Cancelable {
|
||||
tasks[this.id] = this
|
||||
executor.execute(this.run.bind(this))
|
||||
return {
|
||||
cancel: () => {
|
||||
return this.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user