[2.x] Adds scheduler proxy command to normalize sub-minute schedules #167
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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:
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.