Feature: Eventbridge v2: add schedule executor#10817
Conversation
424f308 to
ef1d553
Compare
LocalStack Community integration with Pro 2 files ± 0 2 suites ±0 1h 44m 29s ⏱️ + 2m 56s Results for commit 7a82594. ± Comparison against base commit 98dbcbc. This pull request removes 22 and adds 32 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
ef1d553 to
3e52613
Compare
5946c25 to
e5aab49
Compare
af03fb2 to
933ed0a
Compare
| response = aws_client.events.list_targets_by_rule(Rule=rule_name) | ||
| snapshot.match("list-targets", response) | ||
|
|
||
| time.sleep(60) |
There was a problem hiding this comment.
required to wait until rate kicks in - minimum defineable rate duration is 1 minute
| ], | ||
| ) | ||
|
|
||
| time.sleep(120) # required to wait for time delta 1 minute starting from next full minute |
There was a problem hiding this comment.
although cron tab fires in 1 minute, it is required to wait until start of next full minute to begin with due to cold start on AWS.
| self._rule_services_store: RuleServiceDict = {} | ||
| self._target_sender_store: TargetSenderDict = {} | ||
|
|
||
| def on_before_start(self): |
There was a problem hiding this comment.
required to start background thread of job scheduler
| delay_secs = schedule.next( | ||
| default_utc=True | ||
| ) # utc default time format for rule schedule cron | ||
| # TODO fix execute on exact cron time |
There was a problem hiding this comment.
the rework of the job scheduler in v2 needs to deal with executing a schedule cron at the exact specified time, not run the job if it should occur in less than 60 seconds from now.
| del self.jobs[i] | ||
| else: | ||
| i += 1 | ||
| self.jobs = [job for job in self.jobs if job.job_id != job_id] |
There was a problem hiding this comment.
👍
💡 We still need to make such modifications thread-safe using locks in the scheduler rework.
| @pytest.mark.xfail( | ||
| reason="This test is flaky is CI, might be race conditions" # FIXME: investigate and fix | ||
| ) | ||
| def test_scheduled_rule_logs( |
There was a problem hiding this comment.
this test needs to be completely reworked, due to the unknown time requirement this will take, it is being deferred to a later stage since the test case is covered by other tests mostly.
There was a problem hiding this comment.
makes sense 👍
Remember to track it in a backlog item, so we don't forget about it.
joe4dev
left a comment
There was a problem hiding this comment.
LGTM 👍
This PR integrates the same scheduler as EventBridge v1 and improves test coverage and parity (especially related to schedule conversions).
We will still need to tackle the scheduler rework (based on Thomas's PR #9298) in a follow-up, but it makes sense to tackle this separately as part of the "EventBridge Scheduler" roadmap item and focus on EventBridge provider v1 parity here. Sensible decision 👍
| @pytest.mark.xfail( | ||
| reason="This test is flaky is CI, might be race conditions" # FIXME: investigate and fix | ||
| ) | ||
| def test_scheduled_rule_logs( |
There was a problem hiding this comment.
makes sense 👍
Remember to track it in a backlog item, so we don't forget about it.
| del self.jobs[i] | ||
| else: | ||
| i += 1 | ||
| self.jobs = [job for job in self.jobs if job.job_id != job_id] |
There was a problem hiding this comment.
👍
💡 We still need to make such modifications thread-safe using locks in the scheduler rework.
tests/aws/services/events/scheduled_rules/test_events_scheduled_rules_logs.py
Show resolved
Hide resolved
b37f1b8 to
7a82594
Compare
| if not name: | ||
| name = f"test-log-group-{short_uid()}" | ||
|
|
||
| aws_client.logs.create_log_group(logGroupName=name) |
There was a problem hiding this comment.
@maxhoheiser I learned while testing pipes that log groups are not created instantly at AWS. Even worse was that a subsequent describe_log_groups call failed in this example:
log_group_name = f"test-log-group-{short_uid()}"
aws_client.logs.create_log_group(logGroupName=log_group_name)
def _log_group_created():
describe_log_groups_response = aws_client.logs.describe_log_groups(
logGroupNamePattern=log_group_name
)
log_groups = describe_log_groups_response.get("logGroups", [])
return len(log_groups) > 0
# create_log_group does not happen instantly on AWS
assert poll_condition(_log_group_created, timeout=5, interval=0.5)
describe_log_groups_response = aws_client.logs.describe_log_groups(
logGroupNamePattern=log_group_name
)
log_group_arn = describe_log_groups_response["logGroups"][0]["arn"]
cleanups.append(lambda: aws_client.logs.delete_log_group(logGroupName=log_group_name))with the following error:
> log_group_arn = describe_log_groups_response["logGroups"][0]["arn"]
E IndexError: list index out of range
I ended up returning the log_group_arn through the helper. Ideally, we could reuse a reliable fixture.
👉 It might be worth adding a comment to the fixture or implementing a waiter.
Motivation
Rules can have a schedule that invokes the defined (max 5) targets for the rule, not based on incoming events that are matched via a pattern, but this deveined schedule.
https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html
The schedule can either be specified as a rate expression (https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-rate-expressions.html) or as a cron expression (https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html)
Changes
Add validation of schedule cron or rate.
Add schedule function that creates default event or uses custom event input and uses TargetSender to dispatch event.
Fix JobScheduleExecttor to use UTC time, since default cron schedule is in UTC.
Add logic to convert rate to cron.
Expand test suite.