›
byrcsc/laravel-data-sync · 1.x
Schedule sync definitions and pruning through Laravel's scheduler.
Nothing is scheduled until you ask for it, with one exception: sync:prune,
which runs daily whenever schedule registration is on.
Give the definition a schedule() method and it is registered automatically:
use Illuminate\Console\Scheduling\Event;
public function schedule(Event $event): void
{
$event->hourlyAt(15)->withoutOverlapping();
}The $event is the scheduled sync:run <name> command, so the whole scheduler
API is available: ->timezone(), ->between(), ->onOneServer(),
->environments(), and so on.
Declaring the method is the opt-in. A definition that does not declare it is not scheduled, and there is no config key that would schedule it implicitly.
A cron expression in overrides schedules a definition without touching the
class, and wins over a schedule() method on it:
// config/data-sync.php
'overrides' => [
'products' => [
'schedule' => '0 * * * *',
],
],The expression is validated at boot; an invalid one throws an
InvalidConfigurationException. This is the escape hatch for changing timing per
environment without a deploy of the definition itself.
| Goal | Setting |
|---|---|
| Stop scheduling one definition | overrides.<name>.schedule => false |
| Take a definition out of runs and schedules | overrides.<name>.enabled => false |
| Register nothing at all | data-sync.register_schedules => false |
'overrides' => [
'products' => ['schedule' => false],
'legacy-pricing' => ['enabled' => false],
],register_schedules => false also stops the daily sync:prune. If you turn it
off, wire both up yourself:
// routes/console.php
Schedule::command('sync:run products')->hourlyAt(15);
Schedule::command('sync:prune')->dailyAt('02:30');That is the right choice when your scheduling lives entirely in one file, or when an external scheduler, Kubernetes CronJobs, a systemd timer, invokes the commands instead.
With register_schedules on, the package registers, at boot:
sync:prune, daily.sync:run <name> for every enabled definition that has either a cron override
or a declared schedule() method.Registration order follows data-sync.syncs.
Scheduled runs overlap if a feed takes longer than its interval. Two protections apply, and they are not the same thing:
sync:run for the same
definition, scheduled or manual, reports that discovery is already running and
exits successfully. Processing that is already in flight continues.withoutOverlapping() is yours to add in schedule(). It prevents the
command from starting at all while a previous invocation is still running,
which is stricter and worth having on the queued path where the command exits
long before the work finishes.For a feed that arrives once daily but at an unpredictable hour, schedule hourly and let the ledger do the deduplication. Re-running with nothing new to process costs one directory listing.
php artisan schedule:list
php artisan sync:doctorschedule:list shows the registered commands and their expressions.
sync:doctor verifies the configuration those schedules depend on, sources
reachable, disks writable, tables present, which is what turns a silent 2 a.m.
failure into a deploy-time one.
sync:prune removes.overrides shape.