worker threads are only allowed to use one import
hp8wvvvgnj6asjm7 opened this issue · comments
hp8wvvvgnj6asjm7 commented
Issue
Worker threads become unresponsive if they try to access multiple imported classes or functions
Specifications
win7 x64
node: 14.5.0
"devDependencies": {
"@types/node": "^16.11.13",
"@types/ramda": "^0.27.60",
"ts-node": "^10.4.0",
"ts-node-dev": "^1.1.6",
"typescript": "^4.5.4"
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": ".dist",
"moduleResolution": "node",
"declaration": true,
"listFiles": false,
"alwaysStrict": true,
"noUnusedLocals": false,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"pretty": true,
"sourceMap": false,
"types": ["node"],
// "rootDir": "sys",
// "skipLibCheck": true,
// "noStrictGenericChecks": true,
// "noUnusedParameters": false,
// "experimentalDecorators": true,
// "emitDecoratorMetadata": true,
},
"include": ["sys/**/*.ts"],
"exclude": ["node_modules"],
}
Reproduction
main_thread.ts
private create_worker(index, worker_path, worker_args){ return new Promise((rs, rj) => {
let worker:any
// @ts-ignore
if(process[Symbol.for("ts-node.register.instance")]){
worker = new Worker(`require('ts-node/register'); require(require('worker_threads').workerData.path);`, { eval: true, workerData: { path: path.join(__dirname, `${worker_path}.ts`), args: worker_args}})
}else if(process.env.TS_NODE_DEV){
worker = new Worker(`require('ts-node-dev'); require(require('worker_threads').workerData.path);`, { eval: true, workerData: { path: path.join(__dirname, `${worker_path}.ts`), args: worker_args}})
}else{
worker = new Worker(`require(require('worker_threads').workerData.path);`, { eval: true, workerData: { path: path.join(__dirname, `${worker_path}.js`), args: worker_args}})
}
const thread= {
worker,
thread_id: index,
status: null,
load: 0,
}
this._threads.push(thread)
thread.worker.once('online', () => {})
thread.worker.once('error', rj)
thread.worker.once('messageerror', () => {})
thread.worker.once('exit', () => {})
thread.worker.once('message', async (e:any) => {
if(e === true){
worker.on('message', (e) => e.action_type ? this.thread_action_response(e) : this.thread_message(e))
worker.on('error', (e) => e.action_type ? this.thread_action_response(e) : this.thread_error(e))
worker.on('exit', (e) => e.action_type ? this.thread_action_response(e) : this.thread_exit(e))
thread.status = 1
rs(true)
}
})
})}
worker_path.ts
import { w } from './import_1'
import { x } from './import_2'
// NOW BLOCK THE ENTIRE THREAD BY USING
console.log(w) // will log
console.log(x) // won't log
;(async function (service){
parentPort?.on('message', async ({action_id, action_type, action_resolve, data}) => {
switch(action_type){
case 'CREATE_TRACES':{
const { traces, layout } = data
service.create(traces, layout)
action_resolve && parentPort?.postMessage({action_id, action_type, action_success: true})
break
}
case 'UPDATE_TRACES':{
const { name, values, target } = data
service.update(name, values, target)
action_resolve && parentPort?.postMessage({action_id, action_type, action_success: true})
break
}
default:
break
}
})
parentPort?.postMessage(true)
console.log('plot_service_thread')
})(new Service())
import_1.ts
export const w = () => {}
import_2.ts
export const x = () => {}