-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
feat(sns): add delivery policy to sns subscriptions #30830
feat(sns): add delivery policy to sns subscriptions #30830
Conversation
* Algorithms which can be used by SNS to calculate the delays associated with all of the retry attempts between the first and last retries in the backoff phase. | ||
*/ | ||
export enum BackoffFunction { | ||
/** Arithmetic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not the best doc I've ever written 😅 , the best indicator of to what these each of these do that I found was an image at the very bottom of the doc page here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html - suggestions welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't come up with a good description either, but I thought it would be good to at least add a link to this diagram, which shows the differences in the behavior of each backoff function.
However, it seems that this diagram doesn't exist in English😓
In Japanese: https://docs.aws.amazon.com/de_de/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy
In English: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html
I would appreciate it if you could consult with the maintainer again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would appreciate it if you could consult with the maintainer again.
As in a CDK maintainer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! After my approval, you need to get approval from the CDK maintainer. I would appreciate it if you could kindly check it at that time!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right np, I thought you might have meant someone in the SNS team or something 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** The minimum delay for a retry (in seconds). Must be at least 1 and not exceed `maxDelayTarget`. | ||
* @default 20 | ||
*/ | ||
readonly minDelayTarget: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only, this and the next two appear to be mandatory if healthyRetryPolicy
is specified, thought I can't find any specific doc for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be correct to assume that if these are not set, it will result in an error during deployment? If so, I am curious when the default values would be set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I recall correctly from testing, it's required if and only if healthyRetryPolicy
itself is specified, and so the default values would be set in the case healthyRetryPolicy
is not specified (perhaps it's confusing to mention a default in the doc 🤔)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making these two props optional and explicitly setting the default values documented within the L2 construct? These properties may be required in CloudFormation, but I felt there is no need to make them mandatory in the L2 construct.
readonly minDelayTarget?: Duration;
readonly maxDelayTarget?: Duration;
const minDelayTarget = healthyRetryPolicy.minDelayTarget ?? Duration.seconds(20);
const maxDelayTarget = healthyRetryPolicy.maxDelayTarget ?? Duration.seconds(20);
Hi This PR has been pending for community review for a while. Please consider posting it on the #contributing channel in cdk.dev. Community members will be on the lookout there as well for possible reviews. Check How to get your P2 PR community reviewed for more details. |
Thanks, I've posted on the channel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for creating such a wonderful PR! I’ve quickly reviewed it!
/** Linear. | ||
*/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
/** Linear. | ||
*/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
/** Geometric. | ||
*/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
* Algorithms which can be used by SNS to calculate the delays associated with all of the retry attempts between the first and last retries in the backoff phase. | ||
*/ | ||
export enum BackoffFunction { | ||
/** Arithmetic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't come up with a good description either, but I thought it would be good to at least add a link to this diagram, which shows the differences in the behavior of each backoff function.
However, it seems that this diagram doesn't exist in English😓
In Japanese: https://docs.aws.amazon.com/de_de/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy
In English: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html
I would appreciate it if you could consult with the maintainer again.
/** The maximum number of deliveries per second, per subscription. | ||
* @default - no throttling | ||
*/ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
/** The minimum delay for a retry (in seconds). Must be at least 1 and not exceed `maxDelayTarget`. | ||
* @default 20 | ||
*/ | ||
readonly minDelayTarget: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be correct to assume that if these are not set, it will result in an error during deployment? If so, I am curious when the default values would be set.
if (healthyRetryPolicy.minDelayTarget < 1 || healthyRetryPolicy.minDelayTarget > delayTargetLimit) { | ||
throw new Error(`minDelayTarget must be between 1 and ${delayTargetLimit} inclusive`); | ||
} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
if (healthyRetryPolicy.maxDelayTarget < 1 || healthyRetryPolicy.maxDelayTarget > delayTargetLimit) { | ||
throw new Error(`maxDelayTarget must be between 1 and ${delayTargetLimit} inclusive`); | ||
} | ||
if (healthyRetryPolicy.minDelayTarget > healthyRetryPolicy.maxDelayTarget) { | ||
throw new Error('minDelayTarget must not exceed maxDelayTarget'); | ||
} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
throw new Error('minDelayTarget must not exceed maxDelayTarget'); | ||
} | ||
const numRetriesLimit = 100; | ||
if (healthyRetryPolicy.numRetries < 0 || healthyRetryPolicy.numRetries > numRetriesLimit) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah good catch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has the integer check been added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, forgot to push a commit 😅
@@ -136,6 +144,43 @@ export class Subscription extends Resource { | |||
throw new Error('Subscription role arn is required field for subscriptions with a firehose protocol.'); | |||
} | |||
|
|||
if (props.deliveryPolicy) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
Thanks for the review! Hopefully I've addressed everything |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the revisions. I’ve added a few more comments. Once you address those, I plan to approve.
if (healthyRetryPolicy.numRetries < 0 || healthyRetryPolicy.numRetries > numRetriesLimit) { | ||
throw new Error(`numRetries must be between 0 and ${numRetriesLimit} inclusive`); | ||
} | ||
if (healthyRetryPolicy.numNoDelayRetries && healthyRetryPolicy.numNoDelayRetries < 0) { | ||
throw new Error('numNoDelayRetries must be zero or greater'); | ||
} | ||
if (healthyRetryPolicy.numMinDelayRetries && healthyRetryPolicy.numMinDelayRetries < 0) { | ||
throw new Error('numMinDelayRetries must be zero or greater'); | ||
} | ||
if (healthyRetryPolicy.numMaxDelayRetries && healthyRetryPolicy.numMaxDelayRetries < 0) { | ||
throw new Error('numMaxDelayRetries must be zero or greater'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cloud you please show the props value like below?
throw new Error(`numRetries must be between 0 and ${numRetriesLimit} inclusive, got: ${healthyRetryPolicy.numRetries}`);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for you contribution! I've approved this, but I kindly request a minor correction.
minDelayTarget: (healthyRetryPolicy.minDelayTarget === undefined)? 20 : healthyRetryPolicy.minDelayTarget.toSeconds(), | ||
maxDelayTarget: (healthyRetryPolicy.maxDelayTarget === undefined)? 20 : healthyRetryPolicy.maxDelayTarget.toSeconds(), | ||
numRetries: (healthyRetryPolicy.numRetries === undefined)? 3: healthyRetryPolicy.numRetries, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minDelayTarget: (healthyRetryPolicy.minDelayTarget === undefined)? 20 : healthyRetryPolicy.minDelayTarget.toSeconds(), | |
maxDelayTarget: (healthyRetryPolicy.maxDelayTarget === undefined)? 20 : healthyRetryPolicy.maxDelayTarget.toSeconds(), | |
numRetries: (healthyRetryPolicy.numRetries === undefined)? 3: healthyRetryPolicy.numRetries, | |
minDelayTarget: (healthyRetryPolicy.minDelayTarget === undefined) ? 20 : healthyRetryPolicy.minDelayTarget.toSeconds(), | |
maxDelayTarget: (healthyRetryPolicy.maxDelayTarget === undefined) ? 20 : healthyRetryPolicy.maxDelayTarget.toSeconds(), | |
numRetries: (healthyRetryPolicy.numRetries === undefined) ? 3: healthyRetryPolicy.numRetries, |
👍 And thanks again, I really appreciate you taking the time 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for contributing! Left some feedback.
}); | ||
|
||
} | ||
|
||
private renderDeliveryPolicy(deliveryPolicy: DeliveryPolicy, protocol: SubscriptionProtocol): any { | ||
if (protocol !== SubscriptionProtocol.HTTP && protocol !== SubscriptionProtocol.HTTPS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
if (protocol !== SubscriptionProtocol.HTTP && protocol !== SubscriptionProtocol.HTTPS) { | |
if (![SubscriptionProtocol.HTTP, SubscriptionProtocol.HTTPS].includes(protocol)) { |
const minDelayTarget = healthyRetryPolicy.minDelayTarget; | ||
const maxDelayTarget = healthyRetryPolicy.maxDelayTarget; | ||
if (minDelayTarget !== undefined) { | ||
if (minDelayTarget.toMilliseconds() % 1000 !== 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can directly use toSeconds()
which will check if it's a integer second
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about it, but I thought this would be better as the error toSeconds
raises doesn't have the same context we can add here?
} | ||
} | ||
|
||
const numRetriesLimit = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good intention to not use the magic value and define it explicitly. But given the number of validations, I actually think it's more readable to directly use the value like 100 and 3600 in the if condition checks. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I prefer it how it is now? I agree it might be more readable, but I'd prefer keeping hard-coding to a minimum to make refactors safer/simplier, etc
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
@mergify update |
❌ Command disallowed due to command restrictions in the Mergify configuration.
|
@GavinZZ do we have an ETA for this merge? |
This PR has been in the CHANGES REQUESTED state for 3 weeks, and looks abandoned. To keep this PR from being closed, please continue work on it. If not, it will automatically be closed in a week. |
@GavinZZ Could you please merge main branch and approve this PR again? |
Pull request has been modified.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #30830 +/- ##
=======================================
Coverage 77.17% 77.17%
=======================================
Files 105 105
Lines 7169 7169
Branches 1315 1315
=======================================
Hits 5533 5533
Misses 1455 1455
Partials 181 181
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
@LaurenceWarne , @GavinZZ it looks like the reason this PR hasn't proceeded to the next is that we have 2 code coverage test failures (see https://app.codecov.io/gh/aws/aws-cdk/pull/30830/indirect-changes). It looks like the 2 failures are a single problem. The failures just look like some strange side-effect of the change, not an actual problem with the PR. However, I don't think the system will let you move forward until they are addressed. Is someone able to resolve those failures? Sorry I have no idea how to fix them myself. |
Pull request has been modified.
Merged master and it looks to have fixed itself |
Yes, apologize that I didn't get back to you sooner. We've fixed issue with codecov now. Will approve and merge again. |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Comments on closed issues and PRs are hard for our team to see. |
Issue # (if applicable)
Closes #17576.
Reason for this change
To allow setting of delivery policy for appropriate sns subscriptions.
Description of changes
Subscriptions can now take a new parameter
deliveryPolicy
which consists of ahealthyRetryPolicy
, athrottlePolicy
, and arequestPolicy
(each having the same parameters described here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-delivery-retries.html#creating-delivery-policy).Description of how you validated changes
New integration test along with unit tests.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license