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

[2.x] Adds scheduler proxy command to normalize sub-minute schedules #167

Merged
merged 12 commits into from
Dec 19, 2023

Conversation

joedixon
Copy link
Contributor

@joedixon joedixon commented Dec 12, 2023

Vapor's scheduler is invoked every minute by EventBridge. Unlike cron, this is not guaranteed to run at the top of every minute - in fact, here's a note from the AWS docs:

The finest resolution for an EventBridge rule that uses a cron expression is one minute. Your scheduled rule runs within that minute but not on the precise 0th second.

Because EventBridge and target services are distributed, there can be a delay of several seconds between the time the scheduled rule runs and the time the target service performs the action on the target resource.

This is problematic when it comes to sub-minute scheduling which is pretty reliant on the scheduler being invoked at the top of the minute.

In a scenario where an app is running a command using the everySecond() method and where EventBridge doesn't invoke the CLI function until 45s after the top of the minute, the command will actually only run on seconds 45-59 - not ideal.

This PR attempts to remedy that like so:

A new vapor:schedule command has been added. Its job is to act as a sort of proxy between EventBridge and the Laravel scheduler in order to normalize the invocations to the top of the minute.

The first invocation will acquire a lock from the configured cache. This will happen at whatever time it receives the invocation and it keeps the lock until the top of the next minute is reached. At this point, $this->call('schedule:run);` is called and the lock is released.

Now, the next container invoked by EventBridge will attempt to grab the lock. In the event it is invoked prior to the first invocation finishing, it will wait for the lock to be freed. When the lock has been acquired, it waits for the top of the next minute and invokes Laravel's scheduler.

Rinse and repeat.

In the event an unsuitable cache is configured, the command will immediately fallback to schedule:run.

One thing to consider here is that the cli-timeout will need to be set to >= 120 to ensure there is enough time to cover the up to 60s wait to invoke the scheduler and to allow the scheduler to run the repeat events of the sub-minute schedule.

@joedixon joedixon marked this pull request as ready for review December 19, 2023 08:33
@joedixon joedixon merged commit 03bc115 into 2.0 Dec 19, 2023
19 checks passed
@joedixon joedixon deleted the feat/scheduler branch December 19, 2023 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants