diff --git a/package-lock.json b/package-lock.json index 6f4bf89..f9f6334 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2204,6 +2204,11 @@ "retry": "0.12.0" } }, + "async-sema": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.0.tgz", + "integrity": "sha512-+JpRq3r0zjpRLDruS6q/nC4V5tzsaiu07521677Mdi5i+AkaU/aNJH38rYHJVQ4zvz+SSkjgc8FUI7qIZrR+3g==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", diff --git a/package.json b/package.json index 2c188e7..7575ca9 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "analytics-node": "^3.4.0-beta.1", "async": "^3.1.0", "async-retry": "^1.2.3", + "async-sema": "^3.1.0", "aws-sdk": "^2.584.0", "axios": "^0.19.0", "bluebird": "^3.5.5", diff --git a/src/commands/analyze-lambda-cold-starts.js b/src/commands/analyze-lambda-cold-starts.js index 132a9e6..ee4a22d 100644 --- a/src/commands/analyze-lambda-cold-starts.js +++ b/src/commands/analyze-lambda-cold-starts.js @@ -7,6 +7,7 @@ const { checkVersion } = require("../lib/version-check"); const Lambda = require("../lib/lambda"); const Retry = require("async-retry"); const { track } = require("../lib/analytics"); +const { RateLimit } = require("async-sema"); require("colors"); const ONE_MIN_IN_MILLIS = 60 * 1000; @@ -106,6 +107,7 @@ class AnalyzeLambdaColdStartsCommand extends Command { const AWS = getAWSSDK(); const Lambda = new AWS.Lambda({ region }); + const rateLimit = RateLimit(10); // rps this.log( `${region}: analyzing Provisioned Concurrency for ${functionNames.length} functions` @@ -117,6 +119,7 @@ class AnalyzeLambdaColdStartsCommand extends Command { qualifiers = [], marker ) => { + await rateLimit(); const resp = await Lambda.listProvisionedConcurrencyConfigs({ FunctionName: functionName, Marker: marker @@ -171,7 +174,7 @@ class AnalyzeLambdaColdStartsCommand extends Command { return _.fromPairs(pairs); } - async utilizationMetric(functionName, qualifier) { + utilizationMetric(functionName, qualifier) { return { Id: functionName.toLowerCase().replace(/\W/g, "") + @@ -202,12 +205,12 @@ class AnalyzeLambdaColdStartsCommand extends Command { async getProvisionedConcurrencyUtilization(region, functions) { const AWS = getAWSSDK(); const CloudWatch = new AWS.CloudWatch({ region }); - + const startTime = new Date(Date.now() - global.minutes * ONE_MIN_IN_MILLIS); const queries = _.flatMap(functions, ({ functionName, qualifiers }) => qualifiers.map(qualifier => this.utilizationMetric(functionName, qualifier)) ); - + // CloudWatch only allows 100 queries per request const promises = _.chunk(queries, 100).map(async chunk => { const resp = await CloudWatch.getMetricData({