forked from Mirrors/doipjs
289 lines
No EOL
8.7 KiB
JavaScript
289 lines
No EOL
8.7 KiB
JavaScript
/**
|
|
* workerpool.js
|
|
* https://github.com/josdejong/workerpool
|
|
*
|
|
* Offload tasks to a pool of workers on node.js and in the browser.
|
|
*
|
|
* @version 6.0.2
|
|
* @date 2020-10-03
|
|
*
|
|
* @license
|
|
* Copyright (C) 2014-2020 Jos de Jong <wjosdejong@gmail.com>
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
* use this file except in compliance with the License. You may obtain a copy
|
|
* of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations under
|
|
* the License.
|
|
*/
|
|
|
|
/******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId]) {
|
|
/******/ return installedModules[moduleId].exports;
|
|
/******/ }
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ i: moduleId,
|
|
/******/ l: false,
|
|
/******/ exports: {}
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.l = true;
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
/******/
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
/******/
|
|
/******/ // define getter function for harmony exports
|
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
|
/******/ }
|
|
/******/ };
|
|
/******/
|
|
/******/ // define __esModule on exports
|
|
/******/ __webpack_require__.r = function(exports) {
|
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
/******/ }
|
|
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
/******/ };
|
|
/******/
|
|
/******/ // create a fake namespace object
|
|
/******/ // mode & 1: value is a module id, require it
|
|
/******/ // mode & 2: merge all properties of value into the ns
|
|
/******/ // mode & 4: return value when already ns object
|
|
/******/ // mode & 8|1: behave like require
|
|
/******/ __webpack_require__.t = function(value, mode) {
|
|
/******/ if(mode & 1) value = __webpack_require__(value);
|
|
/******/ if(mode & 8) return value;
|
|
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
|
/******/ var ns = Object.create(null);
|
|
/******/ __webpack_require__.r(ns);
|
|
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
|
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
|
/******/ return ns;
|
|
/******/ };
|
|
/******/
|
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
/******/ __webpack_require__.n = function(module) {
|
|
/******/ var getter = module && module.__esModule ?
|
|
/******/ function getDefault() { return module['default']; } :
|
|
/******/ function getModuleExports() { return module; };
|
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
|
/******/ return getter;
|
|
/******/ };
|
|
/******/
|
|
/******/ // Object.prototype.hasOwnProperty.call
|
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
|
/******/
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
/******/
|
|
/******/
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* worker must be started as a child process or a web worker.
|
|
* It listens for RPC messages from the parent process.
|
|
*/
|
|
|
|
// source of inspiration: https://github.com/sindresorhus/require-fool-webpack
|
|
var requireFoolWebpack = eval(
|
|
'typeof require !== \'undefined\'' +
|
|
' ? require' +
|
|
' : function (module) { throw new Error(\'Module " + module + " not found.\') }'
|
|
);
|
|
|
|
// create a worker API for sending and receiving messages which works both on
|
|
// node.js and in the browser
|
|
var worker = {};
|
|
if (typeof self !== 'undefined' && typeof postMessage === 'function' && typeof addEventListener === 'function') {
|
|
// worker in the browser
|
|
worker.on = function (event, callback) {
|
|
addEventListener(event, function (message) {
|
|
callback(message.data);
|
|
})
|
|
};
|
|
worker.send = function (message) {
|
|
postMessage(message);
|
|
};
|
|
}
|
|
else if (typeof process !== 'undefined') {
|
|
// node.js
|
|
|
|
var WorkerThreads;
|
|
try {
|
|
WorkerThreads = requireFoolWebpack('worker_threads');
|
|
} catch(error) {
|
|
if (typeof error === 'object' && error !== null && error.code === 'MODULE_NOT_FOUND') {
|
|
// no worker_threads, fallback to sub-process based workers
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
if (WorkerThreads &&
|
|
/* if there is a parentPort, we are in a WorkerThread */
|
|
WorkerThreads.parentPort !== null) {
|
|
var parentPort = WorkerThreads.parentPort;
|
|
worker.send = parentPort.postMessage.bind(parentPort);
|
|
worker.on = parentPort.on.bind(parentPort);
|
|
} else {
|
|
worker.on = process.on.bind(process);
|
|
worker.send = process.send.bind(process);
|
|
// register disconnect handler only for subprocess worker to exit when parent is killed unexpectedly
|
|
worker.on('disconnect', function () {
|
|
process.exit(1);
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
throw new Error('Script must be executed as a worker');
|
|
}
|
|
|
|
function convertError(error) {
|
|
return Object.getOwnPropertyNames(error).reduce(function(product, name) {
|
|
return Object.defineProperty(product, name, {
|
|
value: error[name],
|
|
enumerable: true
|
|
});
|
|
}, {});
|
|
}
|
|
|
|
/**
|
|
* Test whether a value is a Promise via duck typing.
|
|
* @param {*} value
|
|
* @returns {boolean} Returns true when given value is an object
|
|
* having functions `then` and `catch`.
|
|
*/
|
|
function isPromise(value) {
|
|
return value && (typeof value.then === 'function') && (typeof value.catch === 'function');
|
|
}
|
|
|
|
// functions available externally
|
|
worker.methods = {};
|
|
|
|
/**
|
|
* Execute a function with provided arguments
|
|
* @param {String} fn Stringified function
|
|
* @param {Array} [args] Function arguments
|
|
* @returns {*}
|
|
*/
|
|
worker.methods.run = function run(fn, args) {
|
|
var f = eval('(' + fn + ')');
|
|
return f.apply(f, args);
|
|
};
|
|
|
|
/**
|
|
* Get a list with methods available on this worker
|
|
* @return {String[]} methods
|
|
*/
|
|
worker.methods.methods = function methods() {
|
|
return Object.keys(worker.methods);
|
|
};
|
|
|
|
worker.on('message', function (request) {
|
|
try {
|
|
var method = worker.methods[request.method];
|
|
|
|
if (method) {
|
|
// execute the function
|
|
var result = method.apply(method, request.params);
|
|
|
|
if (isPromise(result)) {
|
|
// promise returned, resolve this and then return
|
|
result
|
|
.then(function (result) {
|
|
worker.send({
|
|
id: request.id,
|
|
result: result,
|
|
error: null
|
|
});
|
|
})
|
|
.catch(function (err) {
|
|
worker.send({
|
|
id: request.id,
|
|
result: null,
|
|
error: convertError(err)
|
|
});
|
|
});
|
|
}
|
|
else {
|
|
// immediate result
|
|
worker.send({
|
|
id: request.id,
|
|
result: result,
|
|
error: null
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
throw new Error('Unknown method "' + request.method + '"');
|
|
}
|
|
}
|
|
catch (err) {
|
|
worker.send({
|
|
id: request.id,
|
|
result: null,
|
|
error: convertError(err)
|
|
});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Register methods to the worker
|
|
* @param {Object} methods
|
|
*/
|
|
worker.register = function (methods) {
|
|
|
|
if (methods) {
|
|
for (var name in methods) {
|
|
if (methods.hasOwnProperty(name)) {
|
|
worker.methods[name] = methods[name];
|
|
}
|
|
}
|
|
}
|
|
|
|
worker.send('ready');
|
|
|
|
};
|
|
|
|
if (true) {
|
|
exports.add = worker.register;
|
|
}
|
|
|
|
|
|
/***/ })
|
|
/******/ ]);
|
|
//# sourceMappingURL=worker.js.map
|