Rip the worker logic out of message_receiver and add the functionality for it to work with pow. Fix pow tests to work with those changes
parent
37abdc6a4e
commit
6113f13d3a
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,124 @@
|
||||
/* global Worker, window, setTimeout */
|
||||
|
||||
const WORKER_TIMEOUT = 60 * 1000; // one minute
|
||||
|
||||
class TimedOutError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = this.constructor.name;
|
||||
if (typeof Error.captureStackTrace === 'function') {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
} else {
|
||||
this.stack = (new Error(message)).stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WorkerInterface {
|
||||
constructor(path) {
|
||||
this._utilWorker = new Worker(path);
|
||||
this._jobs = Object.create(null);
|
||||
this._DEBUG = false;
|
||||
this._jobCounter = 0;
|
||||
|
||||
this._utilWorker.onmessage = e => {
|
||||
const [jobId, errorForDisplay, result] = e.data;
|
||||
|
||||
const job = this._getJob(jobId);
|
||||
if (!job) {
|
||||
throw new Error(
|
||||
`Received worker reply to job ${jobId}, but did not have it in our registry!`
|
||||
);
|
||||
}
|
||||
|
||||
const { resolve, reject, fnName } = job;
|
||||
|
||||
if (errorForDisplay) {
|
||||
return reject(
|
||||
new Error(
|
||||
`Error received from worker job ${jobId} (${fnName}): ${errorForDisplay}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return resolve(result);
|
||||
};
|
||||
}
|
||||
|
||||
_makeJob (fnName) {
|
||||
this._jobCounter += 1;
|
||||
const id = this._jobCounter;
|
||||
|
||||
if (this._DEBUG) {
|
||||
window.log.info(`Worker job ${id} (${fnName}) started`);
|
||||
}
|
||||
this._jobs[id] = {
|
||||
fnName,
|
||||
start: Date.now(),
|
||||
};
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
_updateJob(id, data) {
|
||||
const { resolve, reject } = data;
|
||||
const { fnName, start } = this._jobs[id];
|
||||
|
||||
this._jobs[id] = {
|
||||
...this._jobs[id],
|
||||
...data,
|
||||
resolve: value => {
|
||||
this._removeJob(id);
|
||||
const end = Date.now();
|
||||
window.log.info(
|
||||
`Worker job ${id} (${fnName}) succeeded in ${end - start}ms`
|
||||
);
|
||||
return resolve(value);
|
||||
},
|
||||
reject: error => {
|
||||
this._removeJob(id);
|
||||
const end = Date.now();
|
||||
window.log.info(
|
||||
`Worker job ${id} (${fnName}) failed in ${end - start}ms`
|
||||
);
|
||||
return reject(error);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
_removeJob(id) {
|
||||
if (this._DEBUG) {
|
||||
this._jobs[id].complete = true;
|
||||
} else {
|
||||
delete this._jobs[id];
|
||||
}
|
||||
}
|
||||
|
||||
_getJob(id) {
|
||||
return this._jobs[id];
|
||||
};
|
||||
|
||||
callWorker(fnName, ...args) {
|
||||
const jobId = this._makeJob(fnName);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this._utilWorker.postMessage([jobId, fnName, ...args]);
|
||||
|
||||
this._updateJob(jobId, {
|
||||
resolve,
|
||||
reject,
|
||||
args: this._DEBUG ? args : null,
|
||||
});
|
||||
|
||||
setTimeout(
|
||||
() => reject(new TimedOutError(`Worker job ${jobId} (${fnName}) timed out`)),
|
||||
WORKER_TIMEOUT
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerInterface,
|
||||
TimedOutError,
|
||||
};
|
Loading…
Reference in New Issue