-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathmeasure-lambda-cold-starts.js
154 lines (137 loc) · 4.33 KB
/
measure-lambda-cold-starts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
const { getAWSSDK } = require("../lib/aws");
const { getLatestVersion, deploy } = require("../lib/sar");
const { startStateMachine, waitForStateMachineOutput } = require("../lib/step-functions");
const { Command, flags } = require("@oclif/command");
const { checkVersion } = require("../lib/version-check");
const fs = require("fs");
const { track } = require("../lib/analytics");
require("colors");
const ApplicationId =
"arn:aws:serverlessrepo:us-east-1:374852340823:applications/measure-cold-start";
const StackName = "serverlessrepo-lumigo-cli-measure-cold-start";
class MeasureLambdaColdStartsCommand extends Command {
async run() {
const { flags } = this.parse(MeasureLambdaColdStartsCommand);
const { functionName, region, profile, invocations, file } = flags;
global.region = region;
global.profile = profile;
checkVersion();
track("measure-lambda-cold-starts", { region, invocations });
this.log(`checking the measure-cold-start SAR in [${region}]`);
const version = await getLatestVersion(ApplicationId);
this.log(`the latest version of measure-cold-start SAR is ${version}`);
this.log(
`looking for deployed CloudFormation stack [${StackName}] in [${region}]`
);
let stateMachineArn;
const findCfnResult = await findCloudFormation(version);
switch (findCfnResult.result) {
case "not found":
this.log("stack is not found");
this.log(
`deploying the measure-cold-start SAR [${version}] to [${region}]`
);
stateMachineArn = (await deploy(ApplicationId, version, StackName))
.StateMachineARN;
break;
case "outdated":
this.log(
`stack is deployed but is running an outdated version [${findCfnResult.version}]`
);
stateMachineArn = (await deploy(ApplicationId, version, StackName, true))
.StateMachineARN;
break;
default:
this.log("stack is deployed and up-to-date");
stateMachineArn = findCfnResult.stateMachineArn;
}
this.log(`the State Machine is ${stateMachineArn}`);
let payload = flags.payload || "{}";
if (file) {
this.log(`loading payload from [${file}]...`);
payload = fs.readFileSync(file, "utf8");
}
// eslint-disable-next-line no-unused-vars
const [_arn, _aws, _states, _region, accountId, ...rest] = stateMachineArn.split(
":"
);
const input = JSON.stringify({
functionName: functionName,
count: invocations,
payload: payload
});
const executionArn = await startStateMachine(stateMachineArn, input);
this.log("State Machine execution started");
this.log(`execution ARN is ${executionArn}`);
const result = await waitForStateMachineOutput(executionArn);
this.log(JSON.stringify(result, null, 2).yellow);
}
}
MeasureLambdaColdStartsCommand.description = "Measures a function's initialization time";
MeasureLambdaColdStartsCommand.flags = {
functionName: flags.string({
char: "n",
description: "name of the Lambda function",
required: true
}),
region: flags.string({
char: "r",
description: "AWS region, e.g. us-east-1",
required: true
}),
profile: flags.string({
char: "p",
description: "AWS CLI profile name",
required: false
}),
invocations: flags.integer({
char: "i",
description: "the number of invocations to run for each configuration",
required: false,
default: 100
}),
payload: flags.string({
char: "e",
description: "the JSON payload to send to the function",
required: false,
default: "{}"
}),
file: flags.string({
char: "f",
description: "file that contains the JSON payload to send to the function",
required: false,
exclusive: ["payload"]
})
};
const findCloudFormation = async version => {
const AWS = getAWSSDK();
const CloudFormation = new AWS.CloudFormation();
try {
const resp = await CloudFormation.describeStacks({
StackName: StackName
}).promise();
const stack = resp.Stacks[0];
const semverTag = stack.Tags.find(
x => x.Key === "serverlessrepo:semanticVersion"
);
const currentVersion = semverTag.Value;
if (currentVersion !== version) {
return {
result: "outdated",
version: currentVersion
};
}
const smArnOutput = stack.Outputs.find(x => x.OutputKey === "StateMachineARN");
const stateMachineArn = smArnOutput.OutputValue;
return {
result: "active",
version: version,
stateMachineArn: stateMachineArn
};
} catch (err) {
return {
result: "not found"
};
}
};
module.exports = MeasureLambdaColdStartsCommand;