1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const ava_1 = require("ava");
|
4 | const index_1 = require("../index");
|
5 | const funcs = require("../test/fixtures/functions");
|
6 | const util_1 = require("../test/fixtures/util");
|
7 | const throttle_1 = require("../src/throttle");
|
8 | async function throughput(t, provider, options) {
|
9 | const lambda = await index_1.faast(provider, funcs, {
|
10 | gc: "off",
|
11 | description: t.title,
|
12 | ...options
|
13 | });
|
14 | lambda.on("stats", s => console.log(s.toString()));
|
15 | try {
|
16 | let completed = 0;
|
17 | const nSamplesPerFunction = 100000000;
|
18 | const pump = new throttle_1.Pump({ concurrency: options.concurrency }, () => lambda.functions.monteCarloPI(nSamplesPerFunction).then(() => completed++));
|
19 | pump.start();
|
20 | await util_1.sleep(options.duration);
|
21 | await pump.drain();
|
22 | const cost = await lambda.costSnapshot();
|
23 | console.log(`Stats: ${lambda.stats()}`);
|
24 | console.log(`Cost:`);
|
25 | console.log(`${cost}`);
|
26 | console.log(`Completed ${completed} calls in ${options.duration / (60 * 1000)} minute(s)`);
|
27 | }
|
28 | finally {
|
29 | await lambda.cleanup();
|
30 | }
|
31 | }
|
32 | async function rampUp(t, provider, options) {
|
33 | const lambda = await index_1.faast(provider, funcs, {
|
34 | gc: "off",
|
35 | description: t.title,
|
36 | ...options
|
37 | });
|
38 | lambda.on("stats", s => console.log(s.toString()));
|
39 | try {
|
40 | const nParallelFunctions = 500;
|
41 | const nSamplesPerFunction = 2000000;
|
42 | const promises = [];
|
43 | for (let i = 0; i < nParallelFunctions; i++) {
|
44 | promises.push(lambda.functions.monteCarloPI(nSamplesPerFunction));
|
45 | }
|
46 | const results = await Promise.all(promises);
|
47 | let insidePoints = 0;
|
48 | let samplePoints = 0;
|
49 | results.forEach(m => {
|
50 | insidePoints += m.inside;
|
51 | samplePoints += m.samples;
|
52 | });
|
53 | console.log(`Stats:\n${lambda.stats()}`);
|
54 | console.log(`inside: ${insidePoints}, samples: ${samplePoints}`);
|
55 | t.is(samplePoints, nParallelFunctions * nSamplesPerFunction);
|
56 | const estimatedPI = (insidePoints / samplePoints) * 4;
|
57 | console.log(`PI estimate: ${estimatedPI}`);
|
58 | t.is(Number(estimatedPI.toFixed(2)), 3.14);
|
59 | const cost = await lambda.costSnapshot();
|
60 | console.log(`Cost: ${cost}`);
|
61 | }
|
62 | finally {
|
63 | await lambda.cleanup();
|
64 | }
|
65 | }
|
66 | const rampUpConfigurations = [
|
67 | { memorySize: 1024, mode: "https", concurrency: 500 },
|
68 | { memorySize: 1024, mode: "queue", concurrency: 500 }
|
69 | ];
|
70 | for (const provider of index_1.providers) {
|
71 | for (const config of rampUpConfigurations) {
|
72 | ava_1.default.serial(util_1.title(provider, "ramp up", config), rampUp, provider, config);
|
73 | }
|
74 | }
|
75 | const throughputConfigurations = [
|
76 | { memorySize: 2048, mode: "https", concurrency: 500, duration: 180 * 1000 },
|
77 | { memorySize: 2048, mode: "queue", concurrency: 500, duration: 180 * 1000 }
|
78 | ];
|
79 | for (const provider of index_1.providers) {
|
80 | for (const config of throughputConfigurations) {
|
81 | ava_1.default.serial(util_1.title(provider, "throughput load test", config), throughput, provider, config);
|
82 | }
|
83 | }
|
84 | ava_1.default.serial(throughput, "local", { memorySize: 64, duration: 60 * 1000 });
|
85 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyZm9ybWFuY2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QtcGVyZi9wZXJmb3JtYW5jZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTZDO0FBQzdDLG9DQUFxRTtBQUNyRSxvREFBb0Q7QUFDcEQsZ0RBQXFEO0FBQ3JELDhDQUF1QztBQUV2QyxLQUFLLFVBQVUsVUFBVSxDQUNyQixDQUFtQixFQUNuQixRQUFrQixFQUNsQixPQUE2QztJQUU3QyxNQUFNLE1BQU0sR0FBRyxNQUFNLGFBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFO1FBQ3hDLEVBQUUsRUFBRSxLQUFLO1FBQ1QsV0FBVyxFQUFFLENBQUMsQ0FBQyxLQUFLO1FBQ3BCLEdBQUcsT0FBTztLQUNiLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRW5ELElBQUk7UUFDQSxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFDbEIsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLENBQUM7UUFDdEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxlQUFJLENBQUMsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVksRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUM5RCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUM3RSxDQUFDO1FBQ0YsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxZQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlCLE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLE1BQU0sSUFBSSxHQUFHLE1B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IjtcbmltcG9ydCB7IENvbW1vbk9wdGlvbnMsIGZhYXN0LCBQcm92aWRlciwgcHJvdmlkZXJzIH0gZnJvbSBcIi4uL2luZGV4XCI7XG5pbXBvcnQgKiBhcyBmdW5jcyBmcm9tIFwiLi4vdGVzdC9maXh0dXJlcy9mdW5jdGlvbnNcIjtcbmltcG9ydCB7IHNsZWVwLCB0aXRsZSB9IGZyb20gXCIuLi90ZXN0L2ZpeHR1cmVzL3V0aWxcIjtcbmltcG9ydCB7IFB1bXAgfSBmcm9tIFwiLi4vc3JjL3Rocm90dGxlXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIHRocm91Z2hwdXQoXG4gICAgdDogRXhlY3V0aW9uQ29udGV4dCxcbiAgICBwcm92aWRlcjogUHJvdmlkZXIsXG4gICAgb3B0aW9uczogQ29tbW9uT3B0aW9ucyAmIHsgZHVyYXRpb246IG51bWJlciB9XG4pIHtcbiAgICBjb25zdCBsYW1iZGEgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIHtcbiAgICAgICAgZ2M6IFwib2ZmXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiB0LnRpdGxlLFxuICAgICAgICAuLi5vcHRpb25zXG4gICAgfSk7XG4gICAgbGFtYmRhLm9uKFwic3RhdHNcIiwgcyA9PiBjb25zb2xlLmxvZyhzLnRvU3RyaW5nKCkpKTtcblxuICAgIHRyeSB7XG4gICAgICAgIGxldCBjb21wbGV0ZWQgPSAwO1xuICAgICAgICBjb25zdCBuU2FtcGxlc1BlckZ1bmN0aW9uID0gMTAwMDAwMDAwO1xuICAgICAgICBjb25zdCBwdW1wID0gbmV3IFB1bXAoeyBjb25jdXJyZW5jeTogb3B0aW9ucy5jb25jdXJyZW5jeSEgfSwgKCkgPT5cbiAgICAgICAgICAgIGxhbWJkYS5mdW5jdGlvbnMubW9udGVDYXJsb1BJKG5TYW1wbGVzUGVyRnVuY3Rpb24pLnRoZW4oKCkgPT4gY29tcGxldGVkKyspXG4gICAgICAgICk7XG4gICAgICAgIHB1bXAuc3RhcnQoKTtcbiAgICAgICAgYXdhaXQgc2xlZXAob3B0aW9ucy5kdXJhdGlvbik7XG4gICAgICAgIGF3YWl0IHB1bXAuZHJhaW4oKTtcbiAgICAgICAgY29uc3QgY29zdCA9IGF3YWl0IGxhbWJkYS5jb3N0U25hcHNob3QoKTtcbiAgICAgICAgY29uc29sZS5sb2coYFN0YXRzOiAke2xhbWJkYS5zdGF0cygpfWApO1xuICAgICAgICBjb25zb2xlLmxvZyhgQ29zdDpgKTtcbiAgICAgICAgY29uc29sZS5sb2coYCR7Y29zdH1gKTtcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgQ29tcGxldGVkICR7Y29tcGxldGVkfSBjYWxscyBpbiAke29wdGlvbnMuZHVyYXRpb24gLyAoNjAgKiAxMDAwKX0gbWludXRlKHMpYFxuICAgICAgICApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGxhbWJkYS5jbGVhbnVwKCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiByYW1wVXAodDogRXhlY3V0aW9uQ29udGV4dCwgcHJvdmlkZXI6IFByb3ZpZGVyLCBvcHRpb25zOiBDb21tb25PcHRpb25zKSB7XG4gICAgY29uc3QgbGFtYmRhID0gYXdhaXQgZmFhc3QocHJvdmlkZXIsIGZ1bmNzLCB7XG4gICAgICAgIGdjOiBcIm9mZlwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogdC50aXRsZSxcbiAgICAgICAgLi4ub3B0aW9uc1xuICAgIH0pO1xuICAgIGxhbWJkYS5vbihcInN0YXRzXCIsIHMgPT4gY29uc29sZS5sb2cocy50b1N0cmluZygpKSk7XG5cbiAgICB0cnkge1xuICAgICAgICBjb25zdCBuUGFyYWxsZWxGdW5jdGlvbnMgPSA1MDA7XG4gICAgICAgIGNvbnN0IG5TYW1wbGVzUGVyRnVuY3Rpb24gPSAyMDAwMDAwO1xuICAgICAgICBjb25zdCBwcm9taXNlczogUHJvbWlzZTxmdW5jcy5Nb250ZUNhcmxvUmV0dXJuPltdID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblBhcmFsbGVsRnVuY3Rpb25zOyBpKyspIHtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2gobGFtYmRhLmZ1bmN0aW9ucy5tb250ZUNhcmxvUEkoblNhbXBsZXNQZXJGdW5jdGlvbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgbGV0IGluc2lkZVBvaW50cyA9IDA7XG4gICAgICAgIGxldCBzYW1wbGVQb2ludHMgPSAwO1xuXG4gICAgICAgIHJlc3VsdHMuZm9yRWFjaChtID0+IHtcbiAgICAgICAgICAgIGluc2lkZVBvaW50cyArPSBtLmluc2lkZTtcbiAgICAgICAgICAgIHNhbXBsZVBvaW50cyArPSBtLnNhbXBsZXM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKGBTdGF0czpcXG4ke2xhbWJkYS5zdGF0cygpfWApO1xuICAgICAgICBjb25zb2xlLmxvZyhgaW5zaWRlOiAke2luc2lkZVBvaW50c30sIHNhbXBsZXM6ICR7c2FtcGxlUG9pbnRzfWApO1xuICAgICAgICB0LmlzKHNhbXBsZVBvaW50cywgblBhcmFsbGVsRnVuY3Rpb25zICogblNhbXBsZXNQZXJGdW5jdGlvbik7XG4gICAgICAgIGNvbnN0IGVzdGltYXRlZFBJID0gKGluc2lkZVBvaW50cyAvIHNhbXBsZVBvaW50cykgKiA0O1xuICAgICAgICBjb25zb2xlLmxvZyhgUEkgZXN0aW1hdGU6ICR7ZXN0aW1hdGVkUEl9YCk7XG4gICAgICAgIHQuaXMoTnVtYmVyKGVzdGltYXRlZFBJLnRvRml4ZWQoMikpLCAzLjE0KTtcbiAgICAgICAgY29uc3QgY29zdCA9IGF3YWl0IGxhbWJkYS5jb3N0U25hcHNob3QoKTtcbiAgICAgICAgY29uc29sZS5sb2coYENvc3Q6ICR7Y29zdH1gKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBsYW1iZGEuY2xlYW51cCgpO1xuICAgIH1cbn1cblxuY29uc3QgcmFtcFVwQ29uZmlndXJhdGlvbnMgPSBbXG4gICAgeyBtZW1vcnlTaXplOiAxMDI0LCBtb2RlOiBcImh0dHBzXCIsIGNvbmN1cnJlbmN5OiA1MDAgfSxcbiAgICB7IG1lbW9yeVNpemU6IDEwMjQsIG1vZGU6IFwicXVldWVcIiwgY29uY3VycmVuY3k6IDUwMCB9XG5dIGFzIGNvbnN0O1xuXG5mb3IgKGNvbnN0IHByb3ZpZGVyIG9mIHByb3ZpZGVycykge1xuICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHJhbXBVcENvbmZpZ3VyYXRpb25zKSB7XG4gICAgICAgIHRlc3Quc2VyaWFsKHRpdGxlKHByb3ZpZGVyLCBcInJhbXAgdXBcIiwgY29uZmlnKSwgcmFtcFVwLCBwcm92aWRlciwgY29uZmlnKTtcbiAgICB9XG59XG5cbmNvbnN0IHRocm91Z2hwdXRDb25maWd1cmF0aW9ucyA9IFtcbiAgICB7IG1lbW9yeVNpemU6IDIwNDgsIG1vZGU6IFwiaHR0cHNcIiwgY29uY3VycmVuY3k6IDUwMCwgZHVyYXRpb246IDE4MCAqIDEwMDAgfSxcbiAgICB7IG1lbW9yeVNpemU6IDIwNDgsIG1vZGU6IFwicXVldWVcIiwgY29uY3VycmVuY3k6IDUwMCwgZHVyYXRpb246IDE4MCAqIDEwMDAgfVxuXSBhcyBjb25zdDtcblxuZm9yIChjb25zdCBwcm92aWRlciBvZiBwcm92aWRlcnMpIHtcbiAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aHJvdWdocHV0Q29uZmlndXJhdGlvbnMpIHtcbiAgICAgICAgdGVzdC5zZXJpYWwoXG4gICAgICAgICAgICB0aXRsZShwcm92aWRlciwgXCJ0aHJvdWdocHV0IGxvYWQgdGVzdFwiLCBjb25maWcpLFxuICAgICAgICAgICAgdGhyb3VnaHB1dCxcbiAgICAgICAgICAgIHByb3ZpZGVyLFxuICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICk7XG4gICAgfVxufVxuXG50ZXN0LnNlcmlhbCh0aHJvdWdocHV0LCBcImxvY2FsXCIsIHsgbWVtb3J5U2l6ZTogNjQsIGR1cmF0aW9uOiA2MCAqIDEwMDAgfSk7XG4iXX0= |
\ | No newline at end of file |