Skip to content

Commit 91680a5

Browse files
committed
Express Lambda infrastructure.
1 parent f21570c commit 91680a5

File tree

1 file changed

+91
-20
lines changed

1 file changed

+91
-20
lines changed

lambda.ts

Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,62 @@ import * as aws from "@pulumi/aws";
22

33
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
44
import axios from 'axios';
5+
import * as Bluebird from 'bluebird';
56
import * as b from 'benny';
67
import * as express from 'express';
8+
import * as fs from 'fs';
79

810
import { project, region, stack } from './config';
911
import { role } from './iam';
1012

13+
const RUN_TIME = 10;
14+
const TOTAL_RUNS = 10;
15+
1116
const lambdas:string[] = [];
1217

13-
for (let arch in ['x86_64', 'arm64']) {
14-
for (let i = 1; i <= 1; i++) { // 7
15-
const name = `${project}-${stack}-${arch}-${i}`;
16-
const size = 128 * i;
18+
const LAYER_X64 = './layer/dist/layer-x64.zip';
19+
const LAYER_ARM64 = './layer/dist/layer-arm64.zip';
20+
21+
if (!fs.existsSync(LAYER_X64) || !fs.existsSync(LAYER_ARM64)) {
22+
throw new Error('Layers not found. Run "npm run layer"');
23+
}
24+
25+
const layerX64 = new aws.lambda.LayerVersion(`${project}-${stack}-layer-x64`, {
26+
code: LAYER_X64,
27+
layerName: `${project}-${stack}-x64`,
28+
compatibleArchitectures: ['x86_64'],
29+
compatibleRuntimes: ['nodejs14.x'],
30+
description: `${project}-${stack} - x64 dependencies`,
31+
});
1732

33+
const layerArm64 = new aws.lambda.LayerVersion(`${project}-${stack}-layer-arm64`, {
34+
code: LAYER_ARM64,
35+
layerName: `${project}-${stack}-arm64`,
36+
compatibleArchitectures: ['arm64'],
37+
compatibleRuntimes: ['nodejs14.x'],
38+
description: `${project}-${stack} - arm64 dependencies`,
39+
});
40+
41+
for (const arch of ['x86_64', 'arm64']) {
42+
for (let i = 7; i <= 13; i++) {
43+
const size = 2 ** i;
44+
const name = `${project}-${stack}-express-${arch}-${size}`;
45+
46+
console.log(name);
1847
lambdas.push(name);
1948

20-
new aws.lambda.CallbackFunction(`${project}-${stack}-lambda-${arch}-${i}`, {
49+
new aws.lambda.CallbackFunction(`${project}-${stack}-lambda-express-${arch}-${i}`, {
2150
name: name,
2251
runtime: 'nodejs14.x',
2352
architectures: [arch],
2453
memorySize: size,
25-
timeout: 60,
54+
timeout: Math.max(60, RUN_TIME),
55+
// layers: [
56+
// arch === 'x86_64' ? layerX64.arn : layerArm64.arn,
57+
// ],
2658
role: role,
27-
description: `${project}-${stack} - ${arch} (${size} MB).`,
28-
callback: (event, context, callback) => {
59+
description: `${project}-${stack} - Express.js (${arch} ${size} MB).`,
60+
callback: (event:any, context, callback) => {
2961
const PORT = 3000;
3062

3163
const app = express();
@@ -46,7 +78,7 @@ for (let arch in ['x86_64', 'arm64']) {
4678

4779
return runner;
4880
}, {
49-
maxTime: 30,
81+
maxTime: event.time,
5082
}),
5183
b.cycle(),
5284
b.complete(() => {
@@ -66,25 +98,64 @@ export const runner = new aws.lambda.CallbackFunction(`${project}-${stack}-lambd
6698
name: `${project}-${stack}-runner`,
6799
runtime: 'nodejs14.x',
68100
memorySize: 128,
69-
timeout: 60,
101+
timeout: 300,
70102
role: role,
71103
description: `${project}-${stack} runner`,
72104
callback: (event, context, callback) => {
73105
const client = new LambdaClient({ region });
106+
const tasks = [];
74107

75-
const tasks = lambdas.map((lambda) => {
76-
return client.send(
77-
new InvokeCommand({
78-
FunctionName: lambda,
79-
InvocationType: '',
80-
})
81-
).then(x => x.Payload);
82-
});
108+
for (let i = 0; i < TOTAL_RUNS; i++) {
109+
const task = async () => {
110+
const subtasks = lambdas.map((lambda) => {
111+
return client.send(
112+
new InvokeCommand({
113+
FunctionName: lambda,
114+
Payload: Buffer.from(JSON.stringify({ time: RUN_TIME })),
115+
})
116+
).then(x => x.Payload);
117+
});
118+
119+
return Promise.all(subtasks)
120+
.then((results) => {
121+
const data:{ [x:string]:number; } = {};
83122

84-
Promise.all(tasks)
123+
results.forEach((res, i) => {
124+
const stats = JSON.parse(Buffer.from(res!).toString('utf-8'));
125+
data[lambdas[i]] = stats.results[0].ops;
126+
});
127+
128+
console.log(`Run #${i}:`, data);
129+
130+
return data;
131+
});
132+
}
133+
134+
tasks.push(task);
135+
}
136+
137+
Bluebird.map(tasks, t => t(), { concurrency: 1 })
85138
.then((results) => {
139+
const result:{ [x:string]:number; } = {};
140+
141+
results.forEach((res, i) => {
142+
Object.keys(res).forEach((x) => {
143+
if (!result[x]) {
144+
result[x] = 0;
145+
}
146+
147+
result[x] += res[x];
148+
});
149+
});
150+
151+
Object.keys(result).forEach((x) => {
152+
result[x] = Math.round(result[x] / results.length);
153+
});
154+
155+
console.log('Result:', result);
86156

157+
callback(null, result);
87158
})
88-
.catch((err) => callback(err));
159+
.catch(err => callback(err));
89160
},
90161
});

0 commit comments

Comments
 (0)