Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 6x 6x 6x 6x 7x 7x 7x 2x 2x 5x 5x 5x 4x 4x 1x 1x 1x 3x 3x 3x 5x 1x 1x 1x 1x 1x 5x 5x | import { strict as assert } from 'assert';
import { isSchedulingFailure, Schedule, SchedulingFailure } from './api-types';
import { ComputeScheduleParameters, ComputeScheduleReturnType, workerFactory } from './worker-interface';
/**
* Runs (in a separate thread) the list scheduling algorithm on the given problem instance and returns the result
* asynchronously.
*
* See [the project page](https://github.com/fschopp/project-planning-js) for more information on the algorithm.
*
* @param args argument list that will be passed on to {@link computeSchedule}() unaltered
* @return promise that will be resolved with the solution or rejected with a {@link SchedulingFailure} containing a
* human-readable failure description if the problem instance is invalid (for example, has a cyclic dependency
* graph)
*/
export function computeScheduleAsync(...args: ComputeScheduleParameters): Promise<Schedule> {
assert(workerFactory.createWorker !== undefined, 'workerFactory.createWorker cannot be undefined');
const worker: Worker | SchedulingFailure = workerFactory.createWorker!();
if (isSchedulingFailure(worker)) {
const failure: SchedulingFailure = worker;
return Promise.reject(failure);
}
let isSettled: boolean = false;
// From MDN: "the executor is called before the Promise constructor even returns the created object"
// Hence all worker callbacks are in place before we send it the "go" message below.
const promise = new Promise<Schedule>((resolve, reject) => {
worker.onmessage = (event: MessageEvent) => {
const result: ComputeScheduleReturnType = event.data;
if (isSchedulingFailure(result)) {
assert(!isSettled, 'Attempted to settle promise more than once.');
reject(result);
isSettled = true;
} else {
assert(!isSettled, 'Attempted to settle promise more than once.');
resolve(result);
isSettled = true;
}
};
worker.onerror = (event: ErrorEvent) => {
worker.terminate();
const failure: SchedulingFailure = 'A runtime error occurred in source file ' +
`${event.filename} (line ${event.lineno}:${event.colno}):\n${event.message}`;
// In theory, the worker could still cause an error after it has sent its last message. However, the ES6
// specification says:
// "Attempting to resolve or reject a resolved promise has no effect."
// https://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects
// Hence, there is no race condition. On the other hand, we don't want to swallow the problem. Therefore, we
// add an assertion:
assert(!isSettled, 'Attempted to settle promise more than once.');
reject(failure);
isSettled = true;
};
});
worker.postMessage(args);
return promise;
}
|