-
Notifications
You must be signed in to change notification settings - Fork 89
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
RFC 474: Event Bridge Scheduler L2 #486
RFC 474: Event Bridge Scheduler L2 #486
Conversation
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.
Hi @filletofish, @Jacco, starting off with a few comments on the proposed APIs. Nothing too major. I'll be back to look at the rest soon.
const oneTimeSchedule = new Schedule(this, 'Schedule', { | ||
schedule: ScheduleExpression.at(new Date(2022, 10, 20, 19, 20, 23)), | ||
target, | ||
scheduleTimeZone: 'America/New_York' |
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.
TimeZone enum is added to core: aws/aws-cdk#24127. We should use it.
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.
Amazing, thanks!
- Make minor changes to README - Add mermaid diagram
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.
Hi! @filletofish @Jacco. I am back, and have just a few more comments on this RFC. Once they are addressed I will swiftly approve and we can get to the implementation. Thanks for all your work thus far!
deadLetterQueue: dlq, | ||
maximumEventAge: Duration.minutes(1), | ||
maximumRetryAttempts: 3 |
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.
are all three of these part of the retry policy?
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.
In CFN only maximum event age and maximum retry attempts are part of retry policy. Would you recommend to organise them similarly in a RetryPolicy
structure as well?
Co-authored-by: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Co-authored-by: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Co-authored-by: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Co-authored-by: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Co-authored-by: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Thank you for your feedback @comcalvi! I have made some updates per your comments. |
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.
A few minor comments from one of the users' perspective. Looking forward to using this feature! 🚀
const cronBasedSchedule = new Schedule(this, 'Schedule', { | ||
schedule: ScheduleExpression.cron({ minute: '0', hour: '23', day: '20', month: '11' }), | ||
target, | ||
scheduleTimeZone: TimeZone.AMERICA_NEW_YORK, |
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 renaming the prop scheduleTimezone
to timezone
to make it short? I feel it is already clear enough that this timezone property is for the schedule.
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 am concerned that the customer might think that timezone is also applied to other properties. For example, Schedule
also has properties startDate
and endDate
, which should be specified in UTC timezone and do not depend on timezone.
So we have these options:
1 - Do nothing
Keep interface as-is with a separate scheduleTimeZone
parameter. It's simple and matches CFN structure https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-scheduler-schedule.html#cfn-scheduler-schedule-scheduleexpressiontimezone
2 - Rename scheduleTimeZone
to timeZone
Not obvious that the property timeZone
does not apply to startDate
and endDate
3 - Add timezone parameter to ScheduleExpression
methods
Example:
const cronBasedSchedule = new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.cron({ minute: '0', hour: '23', day: '20', month: '11', timezone: TimeZone.AMERICA_NEW_YORK}),
target,
description: 'This is a test cron-based schedule that will run at 11:00 PM, on day 20 of the month, only in November in New York timezone',
});
In implementation we will create a class ScheduleExpression
that will inherit from events.Schedule
and will have methods cron(..)
, at(..)
and rate(..)
with timezone as an additional parameter.
Not a bad option. Maybe timezone
will not be that discoverable as in other options.
4 - Create a separate interface with two parameters expression
and timezone
Example:
const cronBasedSchedule = new Schedule(this, 'Schedule', {
scheduleExpression: {
expression: ScheduleExpression.cron({ minute: '0', hour: '23', day: '20', month: '11' }),
timeZone: TimeZone.AMERICA_NEW_YORK
},
target,
description: 'This is a test cron-based schedule that will run at 11:00 PM, on day 20 of the month, only in November in New York timezone',
});
However, I am not sure what name to choose for the new interface as names Schedule
and ScheduleExpression
are already taken. Any recommendations?
All in all, I am probably still leaning to the first as it's the simplest option. Curious if you guys also have any opinion on this question @Jacco, @kaizencc and @comcalvi?
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.
That makes sense, thanks! To me, option 3 or 4 look nice and more cohesive, but at the same time option 1 sounds reasonable. I'm fine with whatever decision is made :)
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 like option 4, with scheduleExpression: { schedule: Schedule, timeZone: TimeZone }
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 like option 4, with scheduleExpression: { schedule: Schedule, timeZone: TimeZone }
But then there will be two classes with names Schedule
. Can't find a better class names, do you have any ideas?
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.
Few things to consider:
How would the original events.Schedule
be changed if timezone support is added for aws-events
. I think it would best added CronOptions
in CDK since it has no meaning for a rate
expressions timeZone
has no meaning. It would be kept separate though because in cloudFormation is would probably not be part of the expression but a separate property like here.
So maybe we should still used events.Schedule
functionality but not inherit and add the timeZone parameter from cron
and at
.
Unflat interfaces give less good code completion in some languages (like python).
Another thing to consider: what if aws-events
at some point adds another type of schedule that is unsupported by aws-scheduler
. We could add an error raising override, but maybe we'd better not inherited?
Maybe implement like this:
import { Duration, TimeZone } from 'aws-cdk-lib';
import * as events from 'aws-cdk-lib/aws-events';
export abstract class ScheduleExpression {
public static at(date: Date, timeZone?: TimeZone): ScheduleExpression {
try {
const literal = date.toISOString().split('.')[0];
return new LiteralScheduleExpression(`at(${literal})`, timeZone)
} catch(e) {
if (e instanceof RangeError){
throw new Error('Invalid date');
}
throw e;
}
}
public static cron(options: events.CronOptions, timeZone?: TimeZone): ScheduleExpression {
return new LiteralScheduleExpression(events.Schedule.cron(options).expressionString, timeZone);
}
public static rate(duration: Duration): ScheduleExpression {
return new LiteralScheduleExpression(events.Schedule.rate(duration).expressionString);
}
public static expression(expression: string, timeZone?: TimeZone) {
return new LiteralScheduleExpression(expression, timeZone);
}
public abstract readonly expressionString: string;
public abstract readonly expressionTimeZone?: TimeZone;
}
class LiteralScheduleExpression extends ScheduleExpression {
constructor(public readonly expressionString: string, public readonly expressionTimeZone?: TimeZone) {
super();
}
public _bind() {}
}
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 like that suggestion @Jacco. It's similar to option 3. I was also thinking about the way to reuse functionality of events.Schedule
with composition, but couldn't come up with a good enough option like yours.
I will add it to the RFC. Thanks!
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.
Agree on not inheriting for now. The ideal scenario is still to put a generic Schedule into core that can be extended by the 4 resources that have the concept of schedule today. But that's out of scope of this RFC.
(autoscaling, app-autoscaling, scheduler, events are the 4 i can think of)
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.
This is great work, I just have a few minor comments
2. **Targets**: A target is an API operation that EventBridge Scheduler calls on your behalf every time your schedule runs. EventBridge Scheduler supports two types of targets: templated targets and universal targets. Templated targets invoke common API operations across a core groups of services. For example, EventBridge Scheduler supports templated targets for invoking AWS Lambda Function or starting execution of Step Function state machine. For API operations that are not supported by templated targets you can use customizeable universal targets. Universal targets support calling more than 6,000 API operations across over 270 AWS services. | ||
3. **Schedule Group**: A schedule group is an Amazon EventBridge Scheduler resource that you use to organize your schedules. Your AWS account comes with a default scheduler group. A new schedule will always be added to a scheduling group. If you do not provide a scheduling group to add to, it will be added to the default scheduling group. You can create up to 500 schedule groups in your AWS account. Groups can be used to organize the schedules logically, access the schedule metrics and manage permissions at group granularity (see details below). Scheduling groups support tagging: with EventBridge Scheduler, you apply tags to schedule groups, not to individual schedules to organize your resources. |
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.
Very nice!
scheduleExpression: ScheduleExpression.cron( | ||
{ minute: '0', hour: '23', day: '20', month: '11' }, | ||
TimeZone.AMERICA_NEW_YORK | ||
), |
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 like this a lot. Why not move the timezone to the struct that's taken as the first argument?
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.
nice one, will add
Co-authored-by: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
This is a request for comments about EventBridge Scheduler L2 Construct. See #474 for
additional details.
APIs are signed off by @kaizencc