Compare commits

..

3 Commits

Author SHA1 Message Date
3c6d69c343 Simplified selectColumnSizeHeuristic 2021-02-25 11:16:16 -07:00
1ff71d099e Update Dockerfile 2021-02-25 11:16:16 -07:00
ae9016fbf6 Update all imports to .js for esm support, use threads.js
threads.js has better support for modules - no need to give a
project-relative path to the worker file, which complicated the build.

Add rudimentary thread pooling w/ execution timeout.
2021-02-25 11:16:16 -07:00

View File

@ -34,7 +34,15 @@ function initialize() {
}
initialize();
function withTimeout<T>(promise: Promise<T>, ms: number, cb: () => Error) {
/**
* Awaits a promise with a timeout.
*
* @param promise the promise to await
* @param ms the timeout in milliseconds
* @param cb a callback to call when the timeout is reached. The promise is
* rejected with whatever gets returned here.
*/
function withTimeout<T>(promise: Promise<T>, ms: number, cb: () => any) {
let timeout: NodeJS.Timeout;
return new Promise<T>((resolve, reject) => {
timeout = setTimeout(() => {
@ -49,31 +57,27 @@ export async function generate(
regionHeight: number,
clues: number
): Promise<Sudoku> {
const proxy = available.shift();
const proxy = available.pop();
if (!proxy) {
throw new Error("No workers available right now. Please try again.");
}
try {
const puzzle: number[] = await withTimeout(
proxy.generate(regionWidth, regionHeight, clues),
TIMEOUT,
() => {
Thread.terminate(proxy);
getWorker().then((worker) => available.push(worker));
return new Error("Timed out. Try reducing the number of clues.");
}
);
const puzzle = await withTimeout<number[]>(
proxy.generate(regionWidth, regionHeight, clues),
TIMEOUT,
() => {
Thread.terminate(proxy);
getWorker().then((worker) => available.push(worker));
return new Error("Timed out. Try reducing the number of clues.");
}
);
available.unshift(proxy);
prettyPrint(regionWidth, regionHeight, puzzle);
return {
regionWidth,
regionHeight,
size: (regionWidth * regionHeight) ** 2,
cells: puzzle,
};
} catch (err) {
throw err;
}
available.push(proxy);
prettyPrint(regionWidth, regionHeight, puzzle);
return {
regionWidth,
regionHeight,
size: (regionWidth * regionHeight) ** 2,
cells: puzzle,
};
}