Closed
Description
Hi,
I am using threads.js for a multi-player game. The main thread spawns two separate workers who each execute the same function.
The two worker threads go ahead and do what they need to do and I await a websocket message to resolve a promise which indicates that the processing is complete.
However, when I call Thread.terminate, I immediately get the following error:
FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place
1: 0xa18150 node::Abort() [node]
2: 0xa1855c node::OnFatalError(char const*, char const*) [node]
3: 0xb9638a v8::Utils::ReportApiFailure(char const*, char const*) [node]
4: 0xb9792e v8::HandleScope::HandleScope(v8::Isolate*) [node]
5: 0xacd89e node::worker::Worker::JoinThread() [node]
6: 0x9baed0 node::Environment::stop_sub_worker_contexts() [node]
7: 0x9bafe0 node::Environment::Stop() [node]
8: 0x9e5e79 node::Stop(node::Environment*) [node]
9: 0xad2926 node::worker::Worker::StopThread(v8::FunctionCallbackInfo<v8::Value> const&) [node]
10: 0xc02529 [node]
11: 0xc04317 v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
12: 0x1409e59 [node]
Aborted (core dumped)
npm ERR! Test failed. See above for more details.
Waiting for the debugger to disconnect...
Here is my code from the master (main thread):
try {
let battleMessage = await new Promise(async (resolve, reject) => {
const ws = new WSClient(WebSocket, `${mockurl.replace('http', 'ws')}/ws`, ['BattleCompleted', 'BattleCreated']);
ws.on('msg', async (message) => {
console.log(`WS Message:`, message);
if (message.subject === 'BattleCompleted') {
resolve(message);
}
});
playerThread1 = await spawn(new Worker(`../scripts/player-setup`));
playerThread2 = await spawn(new Worker(`../scripts/player-setup`));
Thread.events(playerThread1).subscribe(event => {
console.log(`playerThread1 event: ${JSON.stringify(event,null,4)}`);
switch (event.type) {
case 'message':
if (event.data.type === 'result' && event.data.complete === true) {
console.log(`playerThread1 has completed processing`);
}
else if(event.data.type === 'uncaughtError') console.error(`Error from playerThread1: ${JSON.stringify(event.data.error,null,4)}`);
break;
default:
break;
}
});
Thread.events(playerThread2).subscribe(event => {
console.log(`playerThread2 event: ${JSON.stringify(event,null,4)}`);
switch (event.type) {
case 'message':
if (event.data.type === 'result' && event.data.complete === true) {
console.log(`playerThread2 has completed processing`);
}
else if(event.data.type === 'uncaughtError') console.error(`Error from playerThread2: ${JSON.stringify(event.data.error,null,4)}`);
break;
default:
break;
}
});
let player1 = await playerThread1.executePvPBattle(Loaded.location, { playerName: 'SuperElf' });
let player2 = await playerThread2.executePvPBattle(Loaded.location, {
playerName: 'Frodo'
});
});
let winner = JSON.parse(battleMessage.payload);
console.log(`Winner: ${winner}`);
}
catch (e) {
console.error(`Error received ${e}`);
}
finally {
await Thread.terminate(playerThread1);
await Thread.terminate(playerThread2);
}
Everything works normally and I get the console.log for the winner. However, the moment it tries to execute await Thread.terminate(playerThread1);
I get the V8 API error.