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\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
);