geckoboom/scheduler

Cron scheduler for console commands

1.0.5 2022-10-20 09:42 UTC

This package is auto-updated.

Last update: 2024-10-20 13:57:18 UTC


README

Table of Contents

  1. Introduction
  2. Installation
  3. Configuration
  4. Usage
  5. Scheduling
    1. Schedule Frequency Options
    2. Truth Test Constraints 6Advanced

Introduction

Command scheduler is a great approach to managing scheduled console commands on the server. The package allows you to control your task scheduling within the console application. When using a scheduler, only a single cron entry is required on your server.

Installation

This is installable via Composer as This is installable via Composer as geckoboom/scheduler:

composer require geckoboom/scheduler

Configuration

Several steps required to configure scheduler

  1. Provide implementation of Geckoboom\Scheduler\CallerInterface.
class ReflectionCaller implements \Geckoboom\Scheduler\CallerInterface
{
    protected ReflectionContainer $container;
    
    public function call(\Closure $callback){
        $args = [];
        $reflectionMethod = new \ReflectionMethod($callback, '__invoke');
        $args = [];
        foreach ($reflectionMethod->getParameters() as $parameter) {
            if (!$this->container->has($parameter->getName()) && $parameter->isDefaultValueAvailable()) {
                $args[$parameter->getName()] = $parameter->getDefaultValue();
            }
        }
   
        return $this->container->call($callback, $args);     
    }
}
  1. Provide two implementations of EventMutexInterface and ScheduleMutexInterface. The package contains default realizations of these interfaces based on Psr\SimpleCache\CacheInterface dependency. You can do it in such ways
   $container->add(
        \Psr\SimpleCache\CacheInterface::class,
        MyCacheImplementation::class
   );

   $container->add(
        \Geckoboom\Scheduler\EventMutexInterface::class,
        \Geckoboom\Scheduler\EventMutex\CacheEventMutex::class
   );

   $container->add(
        \Geckoboom\Scheduler\ScheduleMutexInterface::class,
        \Geckoboom\Scheduler\ScheduleMutex\CacheScheduleMutex::class
   );

or create your own realizations

    $container->add(
           \Geckoboom\Scheduler\EventMutexInterface::class,
           MyEventMutexImplementation::class
    );

    $container->add(
        \Geckoboom\Scheduler\ScheduleMutexInterface::class,
        MyScheduleMutexImplementation::class
    );
  1. Provide your ScheduleRegistrarInterface dependency.
class MyScheduleRegistrar implements \Geckoboom\Scheduler\ScheduleRegistrarInterface
{
    public function schedule(\Geckoboom\Scheduler\Schedule $schedule) : void {
        $schedule->command('send:emails', ['--option1' => 'value', 'argument1'])
            ->daily()
            ->withoutOverlapping();
        
        $schedule->command('orders:distribute')
            ->mondays()
            ->at('14:00')
            ->runInBackground();
    }
}

...

$container->add(
    \Geckoboom\Scheduler\ScheduleRegistrarInterface::class,
    MyScheduleRegistrar::class
);
  1. Provider Schedule singleton dependency
   $container->addShared(
        \Geckoboom\Scheduler\Schedule::class,
        function ($di): \Geckoboom\Scheduler\Schedule {
            $schedule = new \Geckoboom\Scheduler\Schedule(
                $di->get(\Geckoboom\Scheduler\EventMutexInterface::class),
                $di->get(\Geckoboom\Scheduler\ScheduleMutexInterface::class),
                $di->get(\Geckoboom\Scheduler\CommandBuilder::class),
                '/path/to/project/root',
                new DateTimeZone('Europe/London')
            );
            
            $registrar = $di->get(\Geckoboom\Scheduler\ScheduleRegistrarInterface::class);
            $registrar->schedule($schedule);
            
            return $schedule;
        }
   );

Usage

Now you can create executable script or console command based on the appropriate framework syntax.

   $service = $container->get(\Geckoboom\Scheduler\ScheduleService::class);

   $service->run(new \DateTimeImmutable());

The last step is to add a single cron configuration entry to our server that runs your executable command every minute.

* * * * * cd /path-to-your-project && php /path-to-executable-script >> /dev/null 2>&1