UNPKG

faastjs

Version:

Serverless batch computing made simple.

104 lines 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkIteratorMessages = exports.expectMessage = exports.toArray = exports.sleep = exports.title = exports.noValidateConfigs = exports.configs = exports.record = exports.checkResourcesCleanedUp = exports.withClock = exports.stdev = exports.avg = exports.sum = exports.measureConcurrency = exports.keysOf = void 0; const tslib_1 = require("tslib"); const lolex_1 = tslib_1.__importDefault(require("lolex")); const util_1 = require("util"); const index_1 = require("../../index"); const serialize_1 = require("../../src/serialize"); const shared_1 = require("../../src/shared"); Object.defineProperty(exports, "keysOf", { enumerable: true, get: function () { return shared_1.keysOf; } }); const measureConcurrency = (timings) => timings .map(t => t.start) .map(t => timings.filter(({ start, end }) => start <= t && t < end).length) .reduce((a, b) => Math.max(a, b)); exports.measureConcurrency = measureConcurrency; const sum = (a) => a.reduce((total, n) => total + n, 0); exports.sum = sum; const avg = (a) => (0, exports.sum)(a) / a.length; exports.avg = avg; const stdev = (a) => { const average = (0, exports.avg)(a); return Math.sqrt((0, exports.avg)(a.map(v => (v - average) ** 2))); }; exports.stdev = stdev; async function withClock(fn) { const clock = lolex_1.default.install({ shouldAdvanceTime: true, now: Date.now() }); try { await fn(clock); } finally { clock.uninstall(); } } exports.withClock = withClock; function checkResourcesCleanedUp(t, resources) { for (const key of (0, shared_1.keysOf)(resources)) { t.is(resources[key], undefined); if (resources[key] !== undefined) { console.log(`Resource '${String(key)}' not cleaned up: %O`, resources[key]); } } } exports.checkResourcesCleanedUp = checkResourcesCleanedUp; function record(fn) { const func = Object.assign((...args) => { const rv = fn(...args); func.recordings.push({ args, rv }); index_1.log.info(`func.recordings: %O`, func.recordings); return rv; }, { recordings: [] }); return func; } exports.record = record; exports.configs = [ // { mode: "https", childProcess: false, validateSerialization: true }, { mode: "https", childProcess: true, validateSerialization: true }, // { mode: "queue", childProcess: false, validateSerialization: true }, { mode: "queue", childProcess: true, validateSerialization: true } ]; exports.noValidateConfigs = exports.configs.map(c => ({ ...c, validateSerialization: false })); function title(provider, msg, options) { const desc = options ? (0, util_1.inspect)(options, { breakLength: Infinity }) : ""; return [provider === "local" ? "" : "remote", provider, msg, desc] .filter(x => x !== "") .join(" "); } exports.title = title; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } exports.sleep = sleep; async function toArray(gen) { const result = []; for await (const elem of gen) { result.push(elem); } return result; } exports.toArray = toArray; function expectMessage(t, msg, kind, expected) { t.is(msg.kind, kind); if (msg.kind === kind) { const [value] = (0, serialize_1.deserialize)(msg.value); t.deepEqual(value, expected); } } exports.expectMessage = expectMessage; function checkIteratorMessages(t, rawMessages, arg) { const messages = []; t.is(rawMessages.length, arg.length + 1); for (const msg of rawMessages) { messages[msg.sequence] = msg; } let i = 0; for (; i < arg.length; i++) { expectMessage(t, messages[i], "iterator", { done: false, value: arg[i] }); } expectMessage(t, messages[i], "iterator", { done: true }); } exports.checkIteratorMessages = checkIteratorMessages; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvZml4dHVyZXMvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQ0EsMERBQTBCO0FBQzFCLCtCQUErQjtBQUMvQix1Q0FBMkQ7QUFFM0QsbURBQWtEO0FBQ2xELDZDQUEwQztBQUVqQyx1RkFGQSxlQUFNLE9BRUE7QUFFUixNQUFNLGtCQUFrQixHQUFHLENBQUMsT0FBaUIsRUFBRSxFQUFFLENBQ3BELE9BQU87S0FDRixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0tBQ2pCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0tBQzFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFKN0IsUUFBQSxrQkFBa0Isc0JBSVc7QUFFbkMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQTVELFFBQUEsR0FBRyxPQUF5RDtBQUVsRSxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQVcsRUFBRSxFQUFFLENBQUMsSUFBQSxXQUFHLEVBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUF6QyxRQUFBLEdBQUcsT0FBc0M7QUFFL0MsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFX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YixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDekMsS0FBSyxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUM1QixRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3pCLGFBQWEsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUNELGFBQWEsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzlELENBQUM7QUFoQkQsc0RBZ0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXhlY3V0aW9uQ29udGV4dCB9IGZyb20gXCJhdmFcIjtcbmltcG9ydCBsb2xleCBmcm9tIFwibG9sZXhcIjtcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwidXRpbFwiO1xuaW1wb3J0IHsgQ29tbW9uT3B0aW9ucywgbG9nLCBQcm92aWRlciB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHsgSXRlcmF0b3JSZXNwb25zZU1lc3NhZ2UsIE1lc3NhZ2UgfSBmcm9tIFwiLi4vLi4vc3JjL3Byb3ZpZGVyXCI7XG5pbXBvcnQgeyBkZXNlcmlhbGl6ZSB9IGZyb20gXCIuLi8uLi9zcmMvc2VyaWFsaXplXCI7XG5pbXBvcnQgeyBrZXlzT2YgfSBmcm9tIFwiLi4vLi4vc3JjL3NoYXJlZFwiO1xuaW1wb3J0IHsgVGltaW5nIH0gZnJvbSBcIi4vZnVuY3Rpb25zXCI7XG5leHBvcnQgeyBrZXlzT2YgfTtcblxuZXhwb3J0IGNvbnN0IG1lYXN1cmVDb25jdXJyZW5jeSA9ICh0aW1pbmdzOiBUaW1pbmdbXSkgPT5cbiAgICB0aW1pbmdzXG4gICAgICAgIC5tYXAodCA9PiB0LnN0YXJ0KVxuICAgICAgICAubWFwKHQgPT4gdGltaW5ncy5maWx0ZXIoKHsgc3RhcnQsIGVuZCB9KSA9PiBzdGFydCA8PSB0ICYmIHQgPCBlbmQpLmxlbmd0aClcbiAgICAgICAgLnJlZHVjZSgoYSwgYikgPT4gTWF0aC5tYXgoYSwgYikpO1xuXG5leHBvcnQgY29uc3Qgc3VtID0gKGE6IG51bWJlcltdKSA9PiBhLnJlZHVjZSgodG90YWwsIG4pID0+IHRvdGFsICsgbiwgMCk7XG5cbmV4cG9ydCBjb25zdCBhdmcgPSAoYTogbnVtYmVyW10pID0+IHN1bShhKSAvIGEubGVuZ3RoO1xuXG5leHBvcnQgY29uc3Qgc3RkZXYgPSAoYTogbnVtYmVyW10pID0+IHtcbiAgICBjb25zdCBhdmVyYWdlID0gYXZnKGEpO1xuICAgIHJldHVybiBNYXRoLnNxcnQoYXZnKGEubWFwKHYgPT4gKHYgLSBhdmVyYWdlKSAqKiAyKSkpO1xufTtcblxuZXhwb3J0IHR5cGUgVkNsb2NrID0gbG9sZXguSW5zdGFsbGVkQ2xvY2s8bG9sZXguQ2xvY2s+O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aENsb2NrKGZuOiAoY2xvY2s6IFZDbG9jaykgPT4gUHJvbWlzZTx2b2lkPikge1xuICAgIGNvbnN0IGNsb2NrID0gbG9sZXguaW5zdGFsbCh7IHNob3VsZEFkdmFuY2VUaW1lOiB0cnVlLCBub3c6IERhdGUubm93KCkgfSk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZm4oY2xvY2spO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGNsb2NrLnVuaW5zdGFsbCgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrUmVzb3VyY2VzQ2xlYW5lZFVwPFQgZXh0ZW5kcyBvYmplY3Q+KFxuICAgIHQ6IEV4ZWN1dGlvbkNvbnRleHQsXG4gICAgcmVzb3VyY2VzOiBQYXJ0aWFsPFQ+XG4pIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzT2YocmVzb3VyY2VzKSkge1xuICAgICAgICB0LmlzKHJlc291cmNlc1trZXldLCB1bmRlZmluZWQpO1xuICAgICAgICBpZiAocmVzb3VyY2VzW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFJlc291cmNlICcke1N0cmluZyhrZXkpfScgbm90IGNsZWFuZWQgdXA6ICVPYCwgcmVzb3VyY2VzW2tleV0pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY29yZGVkQ2FsbDxBIGV4dGVuZHMgYW55W10sIFI+IHtcbiAgICBhcmdzOiBBO1xuICAgIHJ2OiBSO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY29yZGVkRnVuY3Rpb248QSBleHRlbmRzIGFueVtdLCBSPiB7XG4gICAgKC4uLmFyZ3M6IEEpOiBSO1xuICAgIHJlY29yZGluZ3M6IEFycmF5PFJlY29yZGVkQ2FsbDxBLCBSPj47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmQ8QSBleHRlbmRzIGFueVtdLCBSPihmbjogKC4uLmFyZ3M6IEEpID0+IFIpIHtcbiAgICBjb25zdCBmdW5jOiBSZWNvcmRlZEZ1bmN0aW9uPEEsIFI+ID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgKC4uLmFyZ3M6IEEpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJ2ID0gZm4oLi4uYXJncyk7XG4gICAgICAgICAgICBmdW5jLnJlY29yZGluZ3MucHVzaCh7IGFyZ3MsIHJ2IH0pO1xuICAgICAgICAgICAgbG9nLmluZm8oYGZ1bmMucmVjb3JkaW5nczogJU9gLCBmdW5jLnJlY29yZGluZ3MpO1xuICAgICAgICAgICAgcmV0dXJuIHJ2O1xuICAgICAgICB9LFxuICAgICAgICB7IHJlY29yZGluZ3M6IFtdIH1cbiAgICApO1xuICAgIHJldHVybiBmdW5jO1xufVxuXG5leHBvcnQgY29uc3QgY29uZmlnczogQ29tbW9uT3B0aW9uc1tdID0gW1xuICAgIC8vIHsgbW9kZTogXCJodHRwc1wiLCBjaGlsZFByb2Nlc3M6IGZhbHNlLCB2YWxpZGF0ZVNlcmlhbGl6YXRpb246IHRydWUgfSxcbiAgICB7IG1vZGU6IFwiaHR0cHNcIiwgY2hpbGRQcm9jZXNzOiB0cnVlLCB2YWxpZGF0ZVNlcmlhbGl6YXRpb246IHRydWUgfSxcbiAgICAvLyB7IG1vZGU6IFwicXVldWVcIiwgY2hpbGRQcm9jZXNzOiBmYWxzZSwgdmFsaWRhdGVTZXJpYWxpemF0aW9uOiB0cnVlIH0sXG4gICAgeyBtb2RlOiBcInF1ZXVlXCIsIGNoaWxkUHJvY2VzczogdHJ1ZSwgdmFsaWRhdGVTZXJpYWxpemF0aW9uOiB0cnVlIH1cbl07XG5cbmV4cG9ydCBjb25zdCBub1ZhbGlkYXRlQ29uZmlncyA9IGNvbmZpZ3MubWFwKGMgPT4gKHtcbiAgICAuLi5jLFxuICAgIHZhbGlkYXRlU2VyaWFsaXphdGlvbjogZmFsc2Vcbn0pKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHRpdGxlKHByb3ZpZGVyOiBQcm92aWRlciwgbXNnOiBzdHJpbmcsIG9wdGlvbnM/OiBvYmplY3QpIHtcbiAgICBjb25zdCBkZXNjID0gb3B0aW9ucyA/IGluc3BlY3Qob3B0aW9ucywgeyBicmVha0xlbmd0aDogSW5maW5pdHkgfSkgOiBcIlwiO1xuICAgIHJldHVybiBbcHJvdmlkZXIgPT09IFwibG9jYWxcIiA/IFwiXCIgOiBcInJlbW90ZVwiLCBwcm92aWRlciwgbXNnLCBkZXNjXVxuICAgICAgICAuZmlsdGVyKHggPT4geCAhPT0gXCJcIilcbiAgICAgICAgLmpvaW4oXCIgXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRvQXJyYXk8VD4oZ2VuOiBBc3luY0l0ZXJhYmxlPFQ+IHwgSXRlcmFibGU8VD4pIHtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IGVsZW0gb2YgZ2VuKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGVsZW0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0TWVzc2FnZTxUPihcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIG1zZzogTWVzc2FnZSxcbiAgICBraW5kOiBcInByb21pc2VcIiB8IFwiaXRlcmF0b3JcIixcbiAgICBleHBlY3RlZDogVFxuKSB7XG4gICAgdC5pcyhtc2cua2luZCwga2luZCk7XG4gICAgaWYgKG1zZy5raW5kID09PSBraW5kKSB7XG4gICAgICAgIGNvbnN0IFt2YWx1ZV0gPSBkZXNlcmlhbGl6ZShtc2cudmFsdWUpO1xuICAgICAgICB0LmRlZXBFcXVhbCh2YWx1ZSwgZXhwZWN0ZWQpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSXRlcmF0b3JNZXNzYWdlcyhcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHJhd01lc3NhZ2VzOiBJdGVyYXRvclJlc3BvbnNlTWVzc2FnZVtdLFxuICAgIGFyZzogc3RyaW5nW11cbikge1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gW107XG4gICAgdC5pcyhyYXdNZXNzYWdlcy5sZW5ndGgsIGFyZy5sZW5ndGggKyAxKTtcbiAgICBmb3IgKGNvbnN0IG1zZyBvZiByYXdNZXNzYWdlcykge1xuICAgICAgICBtZXNzYWdlc1ttc2cuc2VxdWVuY2VdID0gbXNnO1xuICAgIH1cblxuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKDsgaSA8IGFyZy5sZW5ndGg7IGkrKykge1xuICAgICAgICBleHBlY3RNZXNzYWdlKHQsIG1lc3NhZ2VzW2ldLCBcIml0ZXJhdG9yXCIsIHsgZG9uZTogZmFsc2UsIHZhbHVlOiBhcmdbaV0gfSk7XG4gICAgfVxuICAgIGV4cGVjdE1lc3NhZ2UodCwgbWVzc2FnZXNbaV0sIFwiaXRlcmF0b3JcIiwgeyBkb25lOiB0cnVlIH0pO1xufVxuIl19