elektro-potkan/scheduler

Robust job scheduler (cron) with locking

v1.0.0 2021-10-07 06:38 UTC

This package is auto-updated.

Last update: 2024-04-07 10:32:51 UTC


README

Simplifies running periodic jobs of PHP application. Just register all of them to the scheduler and let it to run them at specified time by single call.

Heavily modified fork of contributte/scheduler.

Original package reorganised - jobs moved into individual namespace as well as schedulers.

Console and Nette DI integrations split into separate packages. Run composer suggests for more info.

Usage

The bundled jobs are using the cron syntax.

Example

// init
$scheduler = new ElektroPotkan\Scheduler\Schedulers\LastCheck('path-to-directory-for-storing-locks-and-timestamp');

$scheduler->add(new ElektroPotkan\Scheduler\Jobs\Callback('0 3 * * *',// daily at 3:00 a.m.
	function(): void {
		do_something();
	}
));

// run periodically - optimaly each minute, but heavily depends on Your needs and configured jobs
$scheduler->run();

Cron syntax

See description below. You can also validate your cron using crontab.guru.

  *  *  *  *  *
  -  -  -  -  -
  |  |  |  |  |
  |  |  |  |  |
  |  |  |  |  +----- day of week (0 - 7) (Sunday=0 or 7)
  |  |  |  +---------- month (1 - 12)
  |  |  +--------------- day of month (1 - 31)
  |  +-------------------- hour (0 - 23)
  +------------------------- min (0 - 59)

Schedulers

All the schedulers provided in this package are in the namespace ElektroPotkan\Scheduler\Schedulers.

A list of the available schedulers - the next one is extending the previous one, so it also provides all features of all previous ones.

  • Simple
    • The most basic implementation of scheduler.
    • Does not need any storage.
    • If not called each minute, the job's requested run times might be missed.
    • No locking is provided when running the jobs so if called concurrently, the jobs will be also run concurrently.
  • Locking
    • Uses locks when running the jobs, so if called concurrently, it will skip the job if it is already being run by another instance.
    • Needs directory to store locks.
  • LastCheck
    • Provides $lastCheck timestamp to jobs.
    • If not called each minute, the jobs might use such information to be run at the next call. Eliminates the problem of missing the jobs run times even if not called at their exact time. All jobs provided by this package supports this feature.
  • LastRun
    • Most advanced type of scheduler, provides each job with its $lastRun timestamp.
    • Feature not used by the jobs provided by this package as they do not need it.

Jobs

This package provides 2 basic jobs (located in the namespace ElektroPotkan\Scheduler\Jobs):

  • Callback - Runs given callback.
  • AExpression - Abstract class providing cron syntax support.

Callback job

If You need to call a method myClassMethod of Your class instance $myClass, simply use Callback job:

// run each minute by cron syntax
$job = new ElektroPotkan\Scheduler\Jobs\Callback('* * * * *', [$myClass, 'myClassMethod']);
$scheduler->add($job);

Custom cron-syntax job

To get more flexibility for Your job but use cron syntax effortlessly, extend the AExpression job:

class MyCronJob extends ElektroPotkan\Scheduler\Jobs\AExpression {
	private $myDataSource;
	
	
	public function __construct(string $cron, $myDataSource){
		parent::__construct($cron);
		$this->myDataSource = $myDataSource;
	}
	
	public function run(): void {
		$this->myDataSource->runSomePeriodicTask();
	}
}

$job = new MyCronJob('0 0 * * 1', $myDataSource);// run each Monday at midnight
$scheduler->add($job);

Custom job

For full freedom with Your job, just implement the ElektroPotkan\Scheduler\IJob interface:

class MyJob implements ElektroPotkan\Scheduler\IJob {
	private $dateService;
	
	private $statisticsService;
	
	
	public function __construct($dateService, $statisticsService){
		$this->dateService = $dateService;
		$this->statisticsService = $statisticsService;
	}
	
	public function isDue(
		DateTimeInterface $now,
		?DateTimeInterface $lastCheck = null,
		?DateTimeInterface $lastRun = null
	): bool {
		return $this->dateService->isRightTime($now);
	}
	
	public function run(): void {
		$this->statisticsService->calculate();
	}
}

Logging

To log info and errors from built-in schedulers, You need to provide an implementation of ElektroPotkan\Scheduler\ILogger interface via setLogger call:

// $logger implements ElektroPotkan\Scheduler\ILogger
$scheduler->setLogger($logger);

If You are using Tracy, You can use the provided TracyLogger:

// $logger implements Tracy\ILogger
$scheduler->setLogger(new ElektroPotkan\Scheduler\TracyLogger($logger));

Authors

Info

Versioning

This project uses Semantic Versioning 2.0.0 (semver.org).

Branching

This project uses slightly modified Git-Flow Workflow and Branching Model:

License

You may use this program under the terms of the MIT License.

See file LICENSE.