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; } |