Skip to content

Commit ae7c8f0

Browse files
authored
fixed heap and mem issues (#813)
Co-authored-by: hickeydh <hickeydh@amazon.com>
1 parent 5d7282c commit ae7c8f0

File tree

5 files changed

+82
-46
lines changed

5 files changed

+82
-46
lines changed

src/core/cdk/src/initial-setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export namespace InitialSetup {
151151
ORGANIZATIONS_ITEM_ID: 'organizations',
152152
DYNAMODB_PARAMETERS_TABLE_NAME: parametersTable.tableName,
153153
DEPLOY_STACK_PAGE_SIZE: props.pageSize,
154+
COMPUTE_TYPE: props.codebuildComputeType,
154155
},
155156
});
156157

src/deployments/cdk/cdk.ts

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { CdkToolkit } from './toolkit';
33
import * as app from './src/app';
44
import microstats from 'microstats';
55
import { debugModeEnabled } from '@aws-cdk/core/lib/debug';
6+
import * as v8 from 'v8';
7+
8+
const PAGE_SIZE = parseInt(process.env.DEPLOY_STACK_PAGE_SIZE) || 850;
69

710
process.on('unhandledRejection', (reason, _) => {
811
console.error(reason);
@@ -17,16 +20,45 @@ microstats.on('disk', function (value) {
1720
microstats.on('cpu', function (value) {
1821
console.log('CPU:', value);
1922
});
20-
let microstatsOptions = { frequency: '5s' };
23+
let microstatsOptions = {
24+
frequency: 'onalert',
25+
memoryalert: { used: '>80%' },
26+
cpualert: { load: '>90%' },
27+
diskalert: { used: '>70%' },
28+
};
2129
/**
2230
* Entrypoint for bootstrapping, deploying and synthesizing CDK apps.
2331
*/
2432

33+
const convertToMegabytes = (num: number) => {
34+
return `${(num / 1024 / 1024).toFixed(2)} MB`;
35+
};
36+
37+
const getHeapStatistics = () => {
38+
const heapstats = v8.getHeapStatistics();
39+
40+
return {
41+
totalHeapSize: convertToMegabytes(heapstats.total_heap_size),
42+
totalHeapSizeExecutable: convertToMegabytes(heapstats.total_heap_size_executable),
43+
totalPhysicalSize: convertToMegabytes(heapstats.total_physical_size),
44+
totalAvailableSize: convertToMegabytes(heapstats.total_available_size),
45+
usedHeapSize: convertToMegabytes(heapstats.used_heap_size),
46+
heapSizeLimit: convertToMegabytes(heapstats.heap_size_limit),
47+
usedHeapSizePercentage: ((heapstats.used_heap_size / heapstats.heap_size_limit) * 100).toFixed(2),
48+
mallocedMemory: convertToMegabytes(heapstats.malloced_memory),
49+
peakMallocedMemory: convertToMegabytes(heapstats.peak_malloced_memory),
50+
doesZapGarbage: heapstats.does_zap_garbage,
51+
nativeContexts: heapstats.number_of_native_contexts,
52+
detachedContexts: heapstats.number_of_detached_contexts,
53+
};
54+
};
55+
2556
async function main() {
2657
if (debugModeEnabled()) {
2758
microstats.start(microstatsOptions, err => {
2859
console.log(err);
2960
});
61+
console.log(getHeapStatistics());
3062
}
3163
const usage = `Usage: cdk.ts <command> [<command>] --phase PHASE [--region REGION] [--account-key ACCOUNT_KEY] [--parallel]`;
3264
const args = mri(process.argv.slice(2), {
@@ -54,26 +86,29 @@ async function main() {
5486
phaseId: `${phase}`,
5587
region: args.region,
5688
accountKey: args['account-key'],
57-
// Make sure templates and assets do not build in to the same directory
5889
useTempOutputDir: true,
5990
});
6091
console.log(`Total stacks = ${apps.length}`);
61-
const appDeploymentPaging = [];
62-
63-
const toolkit = await CdkToolkit.create(apps);
64-
65-
if (commands.includes('bootstrap')) {
66-
await toolkit.bootstrap();
67-
}
68-
if (commands.includes('synth')) {
69-
await toolkit.synth();
92+
let appsPage = [];
93+
for (let i = 0; i < apps.length; i++) {
94+
appsPage.push(apps[i]);
95+
console.log(`deploying stack ${i + 1} of ${apps.length}`);
96+
if (appsPage.length > PAGE_SIZE - 1 || i === apps.length - 1) {
97+
const toolkit = await CdkToolkit.create(appsPage);
98+
if (commands.includes('bootstrap')) {
99+
await toolkit.bootstrap();
100+
}
101+
if (commands.includes('synth')) {
102+
await toolkit.synth();
103+
}
104+
if (commands.includes('deploy')) {
105+
await toolkit.deployAllStacks({
106+
parallel,
107+
});
108+
}
109+
appsPage = [];
110+
}
70111
}
71-
if (commands.includes('deploy')) {
72-
await toolkit.deployAllStacks({
73-
parallel,
74-
});
75-
}
76-
77112
if (debugModeEnabled()) {
78113
microstats.stop();
79114
}

src/deployments/cdk/codebuild-deploy.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
#!/bin/sh
22

3+
if [ "${COMPUTE_TYPE}" = "BUILD_GENERAL1_LARGE" ]; then
4+
echo "The codebuild build type has changed from default to ${COMPUTE_TYPE}, increasing the max_old_space_size to 8192"
5+
export NODE_OPTIONS=--max_old_space_size=8192
6+
elif [ "${COMPUTE_TYPE}" = "BUILD_GENERAL1_2XLARGE" ]; then
7+
echo "The codebuild build type has changed from default to ${COMPUTE_TYPE}, increasing the max_old_space_size to 16384"
8+
export NODE_OPTIONS=--max_old_space_size=16384
9+
else
10+
echo "The codebuild build type is ${COMPUTE_TYPE}"
11+
fi
12+
313
if [ -z "${ACCELERATOR_PHASE}" ]; then
414
echo "The environment variable ACCELERATOR_PHASE has to be set to the path of the app you want to deploy."
515
exit 1

src/deployments/cdk/toolkit.ts

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -147,26 +147,14 @@ export class CdkToolkit {
147147
console.log(`There are no stacks to be deployed`);
148148
return [];
149149
}
150-
let combinedOutputs: StackOutput[] = [];
150+
151+
let combinedOutputs: StackOutput[];
151152
if (parallel) {
152-
const pageSize = this.deploymentPageSize;
153-
console.log(`Deploying ${pageSize} stacks at a time out of ${stacks.length} stacks.`);
154-
let stackPromises: any[] = [];
155-
for (let i = 0; i < stacks.length; i++) {
156-
const stack = stacks[i];
157-
console.log(`deploying stack ${i + 1} of ${stacks.length}`);
158-
159-
stackPromises.push(this.deployStack(stack));
160-
if (stackPromises.length > pageSize - 1 || i === stacks.length - 1) {
161-
const results = await Promise.all(stackPromises);
162-
console.log(`Deployed stacks ${i + 1} of ${stacks.length}`);
163-
stackPromises = [];
164-
if (results) {
165-
combinedOutputs.push(...results);
166-
}
167-
}
168-
}
169-
combinedOutputs = combinedOutputs.flat(2);
153+
// Deploy all stacks in parallel
154+
const promises = stacks.map(stack => this.deployStack(stack));
155+
// Wait for all promises to be fulfilled
156+
const outputsList = await fulfillAll(promises);
157+
combinedOutputs = outputsList.reduce((result, output) => [...result, ...output]);
170158
} else {
171159
// Deploy all stacks sequentially
172160
combinedOutputs = [];
@@ -175,8 +163,8 @@ export class CdkToolkit {
175163
combinedOutputs.push(...output);
176164
}
177165
}
166+
178167
// Merge all stack outputs
179-
console.log(JSON.stringify(combinedOutputs, null, 4));
180168
return combinedOutputs;
181169
}
182170

@@ -186,13 +174,20 @@ export class CdkToolkit {
186174
);
187175

188176
const stackExists = await this.cloudFormation.stackExists({ stack });
189-
console.log(`Stack ${stack.displayName} exists`, stackExists);
177+
console.log(
178+
`Stack ${stack.displayName} in account ${stack.environment.account} in region ${stack.environment.region} exists`,
179+
stackExists,
180+
);
190181

191182
const resources = Object.keys(stack.template.Resources || {});
192183
if (resources.length === 0) {
193-
console.warn(`${stack.displayName}: stack has no resources`);
184+
console.warn(
185+
`${stack.displayName} in account ${stack.environment.account} in region ${stack.environment.region}: stack has no resources`,
186+
);
194187
if (stackExists) {
195-
console.warn(`${stack.displayName}: deleting existing stack`);
188+
console.warn(
189+
`${stack.displayName} in account ${stack.environment.account} in region ${stack.environment.region}: deleting existing stack`,
190+
);
196191
this.destroyStack(stack);
197192
}
198193
return [];

src/installer/cdk/src/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,7 @@ async function main() {
8383
const codebuildComputeType = new cdk.CfnParameter(stack, 'CodeBuild Compute Type', {
8484
description: 'The compute type of the build server for the Accelerator deployments.',
8585
default: codebuild.ComputeType.MEDIUM,
86-
allowedValues: [
87-
codebuild.ComputeType.SMALL,
88-
codebuild.ComputeType.MEDIUM,
89-
codebuild.ComputeType.LARGE,
90-
codebuild.ComputeType.X2_LARGE,
91-
],
86+
allowedValues: [codebuild.ComputeType.MEDIUM, codebuild.ComputeType.LARGE, codebuild.ComputeType.X2_LARGE],
9287
});
9388

9489
const stackDeployPageSize = new cdk.CfnParameter(stack, 'Deployment Page Size', {

0 commit comments

Comments
 (0)