PHP code example of tobento / service-schedule

1. Go to this page and download the library: Download tobento/service-schedule library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tobento / service-schedule example snippets


use Tobento\Service\Clock\SystemClock;
use Tobento\Service\Container\Container;
use Tobento\Service\Console\Console;
use Tobento\Service\Console\Command;
use Tobento\Service\Console\InteractorInterface;
use Tobento\Service\Console\Symfony;
use Tobento\Service\Schedule\Task;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskProcessor;
use Tobento\Service\Schedule\TaskProcessorInterface;
use Tobento\Service\Schedule\ScheduleProcessor;
use Tobento\Service\Schedule\ScheduleProcessorInterface;
use Tobento\Service\Schedule\Schedule;
use Tobento\Service\Schedule\ScheduleInterface;
use Psr\Container\ContainerInterface;
use Psr\Clock\ClockInterface;

// Container bindings:
$container = new Container();
$container->set(ClockInterface::class, new SystemClock());
$container->set(TaskProcessorInterface::class, TaskProcessor::class);
$container->set(ScheduleProcessorInterface::class, ScheduleProcessor::class);

// Schedule:
$container->set(ScheduleInterface::class, function() {
    $schedule = new Schedule(name: 'default');
    
    $schedule->task(
        (new Task\CallableTask(
            callable: static function (): string {
                // do something:
                return 'task output';
            },
        ))->name('demo')
    );
    
    return $schedule;
});

// Console:
$console = new Symfony\Console(
    name: 'app',
    container: $container,
);

$console->addCommand(\Tobento\Service\Schedule\Console\ScheduleRunCommand::class);
$console->addCommand(\Tobento\Service\Schedule\Console\ScheduleListCommand::class);
$console->run();

use Tobento\Service\Schedule\Task\CallableTask;
use Tobento\Service\Schedule\Task\TaskInterface;

$task = new CallableTask(
    callable: static function (SomeService $service, $option): string {
        // do something
        
        // you may return the task output or nothing at all (void):
        return 'task output';
    },
    // you may set data passed to the function:
    params: ['option' => 'value'],
);

var_dump($task instanceof TaskInterface);
// bool(true)

// Specific task methods:
$callable = $task->getCallable();
$params = $task->getParams();

use Tobento\Service\Schedule\Task\CallableTask;

class SampleInvokable
{
    public function __invoke(SomeService $service, $option): string
    {
        // do something
        
        // you may return the task output or nothing at all (void):
        return 'task output';
    }
}

$task = new CallableTask(
    callable: new SampleInvokable(),
    // you may set data passed to the __invoke method:
    params: ['option' => 'value'],
);

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Task\TaskInterface;
use Tobento\Service\Console\ConsoleInterface;
use Tobento\Service\Console\ExecutedInterface;

$task = new CommandTask(
    command: 'command:name',
    // you may set command input data:
    input: [
        // passing arguments:
        'username' => 'Tom',
        // with array value:
        'username' => ['Tom', 'Tim'],
        // passing options:
        '--some-option' => 'value',
        // with array value:
        '--some-option' => ['value'],
    ],
);

var_dump($task instanceof TaskInterface);
// bool(true)

// Specific task methods:
$command = $task->getCommand();
$input = $task->getInput();

// Returning null if task is not processed yet, otherwise the console.
$console = $task->getConsole();
// null|ConsoleInterface

// Returning null if task is not processed yet, otherwise the executed.
$executed = $task->getExecuted();
// null|ExecutedInterface

use Tobento\Service\Schedule\Task\InvokableTask;
use Tobento\Service\Schedule\Task\Schedule\CronExpression;

class SampleTask extends InvokableTask
{
    public function __construct()
    {
        // you may set default parameters:
        $this->id('A unique id');
        $this->name('A task name');
        $this->description('A task description');
        
        // you may set a default schedule:
        $this->schedule(new CronExpression('* * * * *'));
        // or
        $this->cron('* * * * *');
    }
    
    public function __invoke(SomeService $service): string
    {
        // do something
        
        // you may return the task output or nothing at all (void):
        return 'task output';
    }
}

$task = (new SampleTask())->cron('* * * * *');

use Tobento\Service\Schedule\Task\PingTask;
use Tobento\Service\Schedule\Task\TaskInterface;
use Psr\Http\Message\ResponseInterface;

$task = new PingTask(
    uri: 'https://example.com/ping',
    method: 'GET', // default
    options: [],
);

var_dump($task instanceof TaskInterface);
// bool(true)

// Specific task methods:
$uri = $task->getUri();
$method = $task->getMethod();
$options = $task->getOptions();

// Returning null if task is not processed yet, otherwise the response.
$response = $task->getResponse();
// null|ResponseInterface

use Tobento\Service\Schedule\Task\ProcessTask;
use Tobento\Service\Schedule\Task\TaskInterface;
use Symfony\Component\Process\Process;

$task = new ProcessTask(
    process: '/bin/script',
);

// or with a process instance:
$task = new ProcessTask(
    process: Process::fromShellCommandline('/bin/script')
        ->setTimeout(20),
);

var_dump($task instanceof TaskInterface);
// bool(true)

// Specific task methods:
$process = $task->getProcess();

// You may set a unique task id:
$task->id('taskId');

// You may set a task name:
$task->name('A task name');

// You may set a description:
$task->description('A task description');

use Tobento\Service\Schedule\TaskScheduleInterface;
use Tobento\Service\Schedule\Task\Schedule\CronExpression;

// you may set the schedule implementing TaskScheduleInterface
$task->schedule(new CronExpression(
    expression: '* * * * *',
    // you may specify a timezone:
    timezone: 'Europe/Berlin', // string|\DateTimeZone
));

// or you may use the cron method:
$task->cron(
    expression: '* * * * *',
    // you may specify a timezone:
    timezone: 'Europe/Berlin', // string|\DateTimeZone
);

use Butschster\CronExpression\Generator;

$task->cron(Generator::create()->daily());

use Tobento\Service\Schedule\Task\Schedule\CronExpression;
use Tobento\Service\Schedule\TaskScheduleInterface;

$cron = new CronExpression(
    expression: '* * * * *',
    // you may specify a timezone:
    timezone: 'Europe/Berlin', // string|\DateTimeZone
);

var_dump($cron instanceof TaskScheduleInterface);
// bool(true)

use Tobento\Service\Schedule\Task\Schedule\CronExpression;
use Butschster\CronExpression\Generator;

$cron = new CronExpression(
    expression: Generator::create()->daily(),
);

use Tobento\Service\Schedule\Task\Schedule\Dates;
use Tobento\Service\Schedule\TaskScheduleInterface;

$dates = new Dates(
    // Every year yyyy-05-12 15:38
    new \DateTime('2023-05-12 15:38:45'),
    // Every year yyyy-08-24 10:15
    new \DateTimeImmutable('2023-08-24 10:15:33'),
);

var_dump($dates instanceof TaskScheduleInterface);
// bool(true)

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskResultInterface;

// any callable handler:
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\After(static function(TaskResultInterface $result, SomeService $service): void {
        // executes after the task is processed
    }))
    // or using the helper method:
    ->after(static function (TaskResultInterface $result, SomeService $service): void {
        // executes after the task is processed
    });

// or a handler implementing Parameter\AfterTaskHandler
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\After(handler: $handler))
    // or using the helper method:
    ->after(handler: $handler);

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskInterface;

// any callable handler:
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Before(static function(TaskInterface $task, SomeService $service): void {
        // executes before the task is processed
    }))
    // or using the helper method:
    ->before(static function (TaskInterface $task, SomeService $service): void {
        // executes before the task is processed
    });

// or a handler implementing Parameter\BeforeTaskHandler
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Before(handler: $handler))
    // or using the helper method:
    ->before(handler: $handler);

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\TaskSkipException;

// any callable handler:
$task = (new CommandTask('command:name'))
    ->before(static function (): void {
        throw new TaskSkipException('Skipped because ...');
    });

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskResultInterface;

// any callable handler:
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Failed(static function(TaskResultInterface $result, SomeService $service): void {
        // executes if the task failed
    }))
    // or using the helper method:
    ->failed(static function (TaskResultInterface $result, SomeService $service): void {
        // executes if the task failed
    });

// or a handler implementing Parameter\FailedTaskHandler
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Failed(handler: $handler))
    // or using the helper method:
    ->failed(handler: $handler);

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Mail\Message;

$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Mail(
        message: (new Message())->to('[email protected]'),
        handle: ['before', 'after', 'failed'], // default
        // send mail only if task failed:
        // handle: ['failed'],
    ));

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Mail\Message;

$task = (new CommandTask('command:name'))
    ->before(new Parameter\Mail(
        message: (new Message())->to('[email protected]'),
    ))
    ->after(new Parameter\Mail(
        message: (new Message())->to('[email protected]'),
    ))
    ->failed(new Parameter\Mail(
        message: (new Message())->to('[email protected]'),
    ));

use Tobento\Service\Mail\MailerInterface;
use Tobento\Service\Schedule\TaskProcessor;
use Tobento\Service\Container\Container;

$container = new Container();
$container->set(MailerInterface::class, function() {
    // create mailer:
    return $mailer;
});

$taskProcessor = new TaskProcessor($container);

use Tobento\Service\Mail\Message;

$message = (new Message())
    ->from('[email protected]')
    ->to('[email protected]');

use Tobento\Service\Mail\Message;

$message = (new Message())
    ->subject('Some task subject')
    ->to('[email protected]');

Task Status: Failed

Task ID: task-id

Task Name: Task's name

Task Description: Task's description (if any)

Task Output: Failed task's output (if any)

Task Exception: Failed task's exception stack trace (if any)

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;

$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Monitor())
    // or using the helper method:
    ->monitor();

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;

$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Ping(
        uri: 'https://example.com/task',
        method: 'GET', // default
        options: [],
        handle: ['before', 'after', 'failed'], // default
        // pings only if task failed:
        // handle: ['failed'],
    ));

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;

$task = (new CommandTask('command:name'))
    ->before(new Parameter\Ping(
        uri: 'https://example.com/task-before',
    ))
    ->after(new Parameter\Ping(
        uri: 'https://example.com/task-after',
    ))
    ->failed(new Parameter\Ping(
        uri: 'https://example.com/task-failed',
    ));

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskInterface;

$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\SendResultTo(
        file: 'dir/to/file.log',
        // if true sends only output, otherwise the whole result:
        onlyOutput: false, // default
        // if true appends result to file otherwise overwrites file:
        append: true, // default
        handle: ['after', 'failed'], // default
        // send result only after task is processed:
        // handle: ['after'],
    ));

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;

$task = (new CommandTask('command:name'))
    ->after(new Parameter\SendResultTo(
        file: 'dir/to/file-success.log',
    ))
    ->failed(new Parameter\SendResultTo(
        file: 'dir/to/file-failed.log',
    ));

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskInterface;

// using a boolean:
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Skip(
        skip: true,
        
        // You may specify a reason for skipping:
        reason: 'Because of ...'
    ));
    
// using a callable:
$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\Skip(
        skip: static function(TaskInterface $task, SomeService $service)
            // skips if return value is true
            return true;
        },
        
        // You may specify a reason for skipping:
        reason: 'Because of ...'
    ));
    
// or using the helper method:
$task = (new CommandTask('command:name'))
    ->skip(skip: $skip, reason: 'Because of ...');

use Tobento\Service\Schedule\Task\CommandTask;
use Tobento\Service\Schedule\Parameter;

$task = (new CommandTask('command:name'))
    ->parameter(new Parameter\WithoutOverlapping(
        // You may set a unique id. If null it uses the task id.
        id: 'unique-task-id', // null|string
        
        // You may set a maximum expected lock duration in seconds:
        ttl: 86400, // default
    ))
    // or using the helper method:
    ->withoutOverlapping()
    // with id and ttl:
    ->withoutOverlapping(id: 'unique-task-id', ttl: 86400);

use Psr\SimpleCache\CacheInterface;
use Tobento\Service\Schedule\TaskProcessor;
use Tobento\Service\Container\Container;
use Tobento\Service\Cache\Simple\Psr6Cache;
use Tobento\Service\Cache\ArrayCacheItemPool;
use Tobento\Service\Clock\SystemClock;

$container = new Container();
$container->set(CacheInterface::class, function() {
    // create cache:
    return new Psr6Cache(
        pool: new ArrayCacheItemPool(
            clock: new SystemClock(),
        ),
        namespace: 'default',
        ttl: null,
    );
});

$taskProcessor = new TaskProcessor($container);

use Tobento\Service\Schedule\TaskProcessor;
use Tobento\Service\Schedule\TaskProcessorInterface;
use Psr\Container\ContainerInterface;

$taskProcessor = new TaskProcessor(
    container: $container // ContainerInterface
);

var_dump($taskProcessor instanceof TaskProcessorInterface);
// bool(true)

use Tobento\Service\Schedule\TaskInterface;
use Tobento\Service\Schedule\TaskResultInterface;

$result = $taskProcessor->processTask($task); // TaskInterface

var_dump($result instanceof TaskResultInterface);
// bool(true)

use Tobento\Service\Schedule\TaskResult;
use Tobento\Service\Schedule\TaskResultInterface;
use Tobento\Service\Schedule\TaskInterface;

$result = new TaskResult(
    task: $task,
    output: 'task output',
    exception: null, // null|\Throwable
);

var_dump($result instanceof TaskResultInterface);
// bool(true)

// Get the task:
$task = $result->task();
// TaskInterface

// Get the output:
$output = $result->output();
// string

// Get the exception:
$output = $result->exception();
// null|\Throwable

var_dump($result->isSuccessful());
// bool(true)

var_dump($result->isFailure());
// bool(false)

var_dump($result->isSkipped());
// bool(false)

use Tobento\Service\Schedule\TaskResults;
use Tobento\Service\Schedule\TaskResultsInterface;
use Tobento\Service\Schedule\TaskResultInterface;

$results = new TaskResults();

var_dump($results instanceof TaskResultsInterface);
// bool(true)

// Add a task result:
$results->add($result); // TaskResultInterface

// Get all task results:
$taskResults = $results->all();
// iterable<int, TaskResultInterface>

// or just:
foreach($taskResults as $taskResult) {}

// Count all task results:
$number = $results->count();
// int(0)

// Filter all successful task results returning a new instance:
$taskResults = $results->successful();
// TaskResultsInterface

// Filter all failed task results returning a new instance:
$taskResults = $results->failed();
// TaskResultsInterface

// Filter all skipped task results returning a new instance:
$taskResults = $results->skipped();
// TaskResultsInterface

// You may use the filter method for filtering task results
// returning a new instance:
$taskResults = $results->filter(fn(TaskResultInterface $r): bool => is_null($r->exception()));
// TaskResultsInterface

use Tobento\Service\Schedule\Schedule;
use Tobento\Service\Schedule\ScheduleInterface;
use Tobento\Service\Schedule\TaskInterface;

$schedule = new Schedule(name: 'default');

var_dump($schedule instanceof ScheduleInterface);
// bool(true)

// Schedule any task implementing TaskInterface
$schedule->task($task);

// You may get a task by its id returning null if task is not found:
$task = $schedule->getTask(id: 'taskId');
// null|TaskInterface

// You may get all tasks:
$tasks = $schedule->all();
// iterable<int, TaskInterface>

use Tobento\Service\Schedule\Task;
use Tobento\Service\Schedule\Parameter;
use Butschster\CronExpression\Generator;

$schedule->task(
    (new Task\CommandTask(
        command: 'command:name',
    ))
    // schedule task:
    ->cron(Generator::create()->everyTenMinutes())
    // adding parameters:
    ->parameter(Parameter\SendResultTo(
        file: 'dir/to/file.log',
    ))
    // or using helper methods:
    ->withoutOverlapping()
);

$schedule->task(
    (new Task\CallableTask(
        callable: static function (SomeService $service, $option): string {
            // do something
            
            // you may return the task output or nothing at all (void):
            return 'task output';
        },
        // you may set data passed to the function:
        params: ['option' => 'value'],
    ))
    ->name('Some name')
    ->description('Some description')
    // schedule task:
    ->cron(Generator::create()->everyTenMinutes())
    // adding parameters:
    ->parameter(Parameter\SendResultTo(
        file: 'dir/to/file.log',
    ))
    // or using helper methods:
    ->withoutOverlapping()
);

use Tobento\Service\Schedule\ScheduleProcessor;
use Tobento\Service\Schedule\ScheduleProcessorInterface;
use Tobento\Service\Schedule\TaskProcessorInterface;
use Psr\EventDispatcher\EventDispatcherInterface;

$scheduleProcessor = new ScheduleProcessor(
    taskProcessor: $taskProcessor, // TaskProcessorInterface
    // you may set an event dispatcher if you want to support events:
    eventDispatcher: null, // null|EventDispatcherInterface
);

var_dump($scheduleProcessor instanceof ScheduleProcessorInterface);
// bool(true)

use Tobento\Service\Schedule\ScheduleInterface;
use Tobento\Service\Schedule\TaskResultsInterface;

$results = $scheduleProcessor->processSchedule(
    schedule: $schedule, // ScheduleInterface
    now: new \DateTime(), // \DateTimeInterface
);

var_dump($results instanceof TaskResultsInterface);
// bool(true)

use Tobento\Service\Schedule\Event;

use Tobento\Service\Container\Container;
use Tobento\Service\Schedule\Task;
use Tobento\Service\Schedule\Parameter;
use Tobento\Service\Schedule\TaskProcessor;
use Tobento\Service\Schedule\TaskProcessorInterface;
use Tobento\Service\Schedule\ScheduleProcessor;
use Tobento\Service\Schedule\ScheduleProcessorInterface;
use Tobento\Service\Schedule\Schedule;
use Tobento\Service\Schedule\ScheduleInterface;
use Psr\Container\ContainerInterface;

// Container bindings:
$container = new Container();
$container->set(TaskProcessorInterface::class, TaskProcessor::class);
$container->set(ScheduleProcessorInterface::class, ScheduleProcessor::class);

// Schedule tasks:
$schedule = new Schedule(name: 'default');
$schedule->task(
    (new Task\CallableTask(
        callable: static function (): string {
            // do something:
            return 'task output';
        },
    ))->name('demo')
);

// Process the schedule:
$container->get(ScheduleProcessorInterface::class)->processSchedule(
    schedule: $schedule, // ScheduleInterface
    now: new \DateTime(), // \DateTimeInterface
);
skip

php app schedule:run

php app schedule:run --id=taskId --id=anotherTaskId

php app schedule:list

* * * * * cd /path-to-your-project && php schedule.php >> /dev/null 2>&1