const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
if (!isMainThread) {
const { createSolver } = require('../src/solver');
let currentSolver = null;
let currentSession = null;
let solving = false;
parentPort.on('message', async (message) => {
try {
switch (message.type) {
case 'solve':
await handleSolve(message);
break;
case 'stop':
await handleStop(message);
break;
case 'status':
handleStatus(message);
break;
default:
parentPort.postMessage({
type: 'error',
sessionId: message.sessionId,
error: `Unknown message type: ${message.type}`
});
}
} catch (error) {
parentPort.postMessage({
type: 'error',
sessionId: message.sessionId,
error: error.message,
stack: error.stack
});
}
});
async function handleSolve(message) {
if (solving) {
throw new Error('Worker is already solving a problem');
}
solving = true;
currentSession = message.sessionId;
try {
currentSolver = await createSolver({
matrix: message.matrix,
method: message.method || 'adaptive',
tolerance: message.options?.tolerance || 1e-10,
maxIterations: message.options?.maxIterations || 1000,
enableVerification: message.options?.enableVerification || false
});
const startTime = Date.now();
let lastMemoryCheck = startTime;
for await (const update of currentSolver.streamSolve(message.vector)) {
if (!solving || currentSession !== message.sessionId) {
break;
}
const now = Date.now();
let memoryUsage = 0;
if (now - lastMemoryCheck > 5000) { const memInfo = process.memoryUsage();
memoryUsage = Math.round(memInfo.heapUsed / 1024 / 1024); lastMemoryCheck = now;
}
parentPort.postMessage({
type: 'iteration',
sessionId: message.sessionId,
iteration: update.iteration,
residual: update.residual,
convergenceRate: update.convergenceRate,
memoryUsage,
verified: update.verified || false,
timestamp: new Date().toISOString()
});
if (update.converged) {
parentPort.postMessage({
type: 'converged',
sessionId: message.sessionId,
solution: update.solution,
stats: {
iterations: update.iteration,
residual: update.residual,
solveTime: now - startTime,
memoryUsage,
converged: true
}
});
break;
}
}
} catch (error) {
parentPort.postMessage({
type: 'error',
sessionId: message.sessionId,
error: error.message
});
} finally {
solving = false;
currentSolver = null;
currentSession = null;
}
}
async function handleStop(message) {
if (currentSession === message.sessionId) {
solving = false;
if (currentSolver && typeof currentSolver.stop === 'function') {
await currentSolver.stop();
}
parentPort.postMessage({
type: 'stopped',
sessionId: message.sessionId
});
}
}
function handleStatus(message) {
parentPort.postMessage({
type: 'status',
sessionId: message.sessionId,
solving,
currentSession,
memory: process.memoryUsage(),
uptime: process.uptime()
});
}
process.on('uncaughtException', (error) => {
parentPort.postMessage({
type: 'error',
sessionId: currentSession,
error: error.message,
fatal: true
});
process.exit(1);
});
process.on('unhandledRejection', (error) => {
parentPort.postMessage({
type: 'error',
sessionId: currentSession,
error: error.message,
fatal: true
});
process.exit(1);
});
parentPort.postMessage({
type: 'ready',
workerId: process.pid
});
} else {
const path = require('path');
function createSolverWorker() {
return new Worker(__filename);
}
module.exports = { createSolverWorker };
}