Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added awsRequest for aws-sdk call backoff and retry in customResources #8338

Merged
merged 16 commits into from Oct 7, 2020

Conversation

pratik-vii
Copy link
Contributor

@pratik-vii pratik-vii commented Oct 2, 2020

Closes: #8333

@codecov-commenter
Copy link

codecov-commenter commented Oct 2, 2020

Codecov Report

Merging #8338 into master will increase coverage by 0.13%.
The diff coverage is 9.23%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #8338      +/-   ##
==========================================
+ Coverage   88.01%   88.15%   +0.13%     
==========================================
  Files         249      249              
  Lines        9305     9300       -5     
==========================================
+ Hits         8190     8198       +8     
+ Misses       1115     1102      -13     
Impacted Files Coverage Δ
...rces/resources/apiGatewayCloudWatchRole/handler.js 0.00% <0.00%> (ø)
...urces/resources/cognitoUserPool/lib/permissions.js 0.00% <0.00%> (ø)
...esources/resources/cognitoUserPool/lib/userPool.js 0.00% <0.00%> (ø)
...Resources/resources/eventBridge/lib/eventBridge.js 0.00% <0.00%> (ø)
...Resources/resources/eventBridge/lib/permissions.js 0.00% <0.00%> (ø)
...ins/aws/customResources/resources/s3/lib/bucket.js 0.00% <0.00%> (ø)
...ws/customResources/resources/s3/lib/permissions.js 0.00% <0.00%> (ø)
lib/plugins/aws/customResources/resources/utils.js 24.52% <30.00%> (+3.31%) ⬆️
lib/plugins/aws/provider/awsProvider.js 93.04% <0.00%> (ø)
...kage/compile/events/apiGateway/lib/method/index.js 100.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7e4871b...5875539. Read the comment docs.

@pratik-vii pratik-vii marked this pull request as draft October 2, 2020 20:34
@pratik-vii pratik-vii marked this pull request as ready for review October 3, 2020 06:02
Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pratik-vii thanks for giving it a spin.

In given form this change is not effective. Note, that no custom resource logic was configured to new utility. We need to ensure that all of the functions rely on this utility, instead of invoking aws-sdk directly.

Also this implementation does not look complete. I believe serviceInstance needs to be resolved on spot, as it's here: https://github.com/serverless/test/blob/7dfc92e1d0d93c91f1c9affc872afa41fcb1c89b/aws-request.js

@pratik-vii
Copy link
Contributor Author

pratik-vii commented Oct 5, 2020

@medikoo

In given form this change is not effective

I was planning to integrate it once signature is approved, I had doubt to whether to keep aws-sdk instantiation in resource or utility itself. Which you answered already!

I believe serviceInstance needs to be resolved on spot, as it's here:

Sure. Will do. I was thinking of doing the same pattern, but I thought to give responsibility of configuring the aws-sdk instance to resource.

@pratik-vii pratik-vii marked this pull request as draft October 5, 2020 13:45
@pratik-vii pratik-vii marked this pull request as ready for review October 5, 2020 15:53
Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @pratik-vii for update. It looks way better now.

Please see my comments. Also please test it by running integration tests, it's the only way to confirm, we did not break anything with this refactor

const apiGateway = new ApiGateway({ region });
const assignedRoleArn = (await apiGateway.getAccount().promise()).cloudwatchRoleArn;
const assignedRoleArn = (
await awsRequest({ name: 'APIGateway', params: { region } }, 'getAccount').promise()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awsRequest should return promise directly, there should be no need for promise()

}
);

function awsRequest(service, method, ...args) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use async/await

@@ -1,5 +1,7 @@
'use strict';

const AWS = require('aws-sdk');
const _ = require('lodash');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not introduce any dependencies here (note this is packaged for lambda, and we want to avoid npm install)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Will remove the usage of lodash.

- changed awsRequest to async
- removed unnecessary promise in awsRequest
@pratik-vii
Copy link
Contributor Author

@medikoo Thanks for the feedback.

I have updated the PR,

  • Removed usage of lodash
  • Changed awsRequest function to async function

I have tested the changes with dependent integration testcases
apiGateway.test.js
cognitoUserPool.test.js
eventBridge.test.js
s3.test.js

Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @pratik-vii , that looks very good! I have just few minor suggestions. Let me know what you think

// temporary state where just created AWS role is not being ready for use (yet)
await wait(10000);
return updateAccount(++counter);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to keep that try/catch, as in this case we want to catch also non-retryable errors, while awsRequest retries only if error is retryable

requestTry < MAX_AWS_REQUEST_TRY &&
error &&
(error.statusCode === 429 ||
(error.retryable && error.statusCode !== 403 && error.code !== 'CredentialsError'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can limit this to (error.statusCode === 429 || error.retryable), as in Lambda we should not expect credential errors, so it's not the case to consider

(error.statusCode === 429 ||
(error.retryable && error.statusCode !== 403 && error.code !== 'CredentialsError'))
) {
return wait(4000 + Math.random() * 3000).then(() => callAws(++requestTry));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 seconds, is a lot in lambda, let's make it maybe 2000 + Math.random() * 1000, and maybe increase DEFAULT_MAX_AWS_REQUEST_TRY to 8

const callAws = requestTry => {
return serviceInstance[method](...args)
.promise()
.then(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use async/await

- changed backoff time to (2000 + Math.random() * 1000)
Copy link
Contributor

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank youi @pratik-vii ! That looks great

@medikoo medikoo merged commit a3ebc01 into serverless:master Oct 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Workaround "Rate exceeded" errors in custom resources
3 participants