tobento/service-schedule

一个特定间隔运行任务的调度系统。

1.0.0 2023-11-17 07:44 UTC

This package is auto-updated.

Last update: 2024-09-17 09:31:15 UTC


README

一个特定间隔运行任务的调度系统。

目录

入门

使用以下命令添加运行此命令的调度服务项目的最新版本。

composer require tobento/service-schedule

要求

  • PHP 8.0 或更高版本

亮点

  • 框架无关,可与任何项目一起使用
  • 解耦设计

文档

用法

调度任务

要调度任务,您可以使用默认的 调度 或创建符合您需求的调度。

运行计划任务

运行调度处理器的最常见方法是运行每分钟运行的调度:run的cron作业。以下内容应添加到您的生产服务器的crontab中

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

console.php的示例

使用 控制台服务时钟服务容器服务 的示例

composer require tobento/service-console
composer require tobento/service-clock
composer require tobento/service-container
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();

查看任务方法部分,了解更多关于可用方法以及任务参数

可调用对象

您可以考虑使用包含 __invoke 方法的可调用对象

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

查看任务方法部分,了解更多关于可用方法以及任务参数

要求

此命令任务需要 控制台服务

composer require tobento/service-console

可调用任务

您可以通过扩展 InvokableTask::class 来创建可调用任务。当任务正在处理时,将调用 __invoke 方法。

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('* * * * *');

查看任务方法部分,了解更多关于可用方法以及任务参数

Ping任务

Ping任务可以用于ping提供的URI。

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

查看任务方法部分,了解更多关于可用方法以及任务参数

要求

此ping任务需要 Guzzle,PHP HTTP客户端

composer require guzzlehttp/guzzle

进程任务

进程任务可以用于使用 Symfony Process Component 执行shell命令。

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

查看任务方法部分,了解更多关于可用方法以及任务参数

要求

此进程任务需要 Symfony Process Component

composer require symfony/process

任务方法

所有支持以下方法的可用任务

通用任务方法

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

查看“任务计划”部分以获取可用的任务计划。

您可以考虑使用已经可用的cron生成器。

use Butschster\CronExpression\Generator;

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

查看Cron表达式生成器以获取更多示例。

任务调度

Cron表达式

您可以使用CronExpression::class来定义希望任务运行的间隔。

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)

您可以考虑使用已经可用的cron生成器。

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

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

查看Cron表达式生成器以获取更多示例。

日期

您可以使用Dates::class在每年的特定日期运行任务。

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)

任务参数

您可以使用提供的参数,这些参数为任务提供了基本功能,或者创建自定义参数以添加新功能或自定义现有功能以满足您的需求。

所有支持以下参数及其辅助方法的所有任务

之后参数

在任务处理完毕后,执行指定的处理程序。

TaskResultInterface::class将传递给您的处理程序。此外,您还可以请求由传递给任务处理器的容器解析(自动装配)的任何服务。

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

之前参数

在任务处理之前执行指定的处理程序。

TaskInterface::class将传递给您的处理程序。此外,您还可以请求由传递给任务处理器的容器解析(自动装配)的任何服务。

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

跳过任务

如果您想阻止任务被处理但不导致失败,您可以抛出TaskSkipException::class

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 ...');
    });

失败参数

如果任务失败,则执行指定的处理程序。

TaskResultInterface::class将传递给您的处理程序。此外,您还可以请求由传递给任务处理器的容器解析(自动装配)的任何服务。

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

邮件参数

可以使用mail参数在任务处理之前和/或之后或任务失败时使用邮件服务发送邮件。

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('admin@example.com'),
        handle: ['before', 'after', 'failed'], // default
        // send mail only if task failed:
        // handle: ['failed'],
    ));

此外,您还可以使用beforeafterfailed辅助方法。

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('admin@example.com'),
    ))
    ->after(new Parameter\Mail(
        message: (new Message())->to('admin@example.com'),
    ))
    ->failed(new Parameter\Mail(
        message: (new Message())->to('admin@example.com'),
    ));

要求

此参数需要邮件服务

首先,安装邮件服务

composer require tobento/service-mail

最后,它需要将MailerInterface::class绑定到传递给任务处理器的容器。

使用容器服务的示例

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('from@example.com')
    ->to('admin@example.com');

邮件内容

您可以设置一个消息主题,否则将使用任务名称

use Tobento\Service\Mail\Message;

$message = (new Message())
    ->subject('Some task subject')
    ->to('admin@example.com');

发送的邮件如下所示

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)

监控参数

可以使用monitor参数来监控任务过程,例如启动时间、运行时间和内存使用情况。

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

Ping参数

可以使用ping参数ping提供的URI。

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'],
    ));

将根据其处理状态添加一个X-Task-Status头,其值可以是“Starting”、“Success”或“Failed”。

此外,您还可以使用beforeafterfailed辅助方法。

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',
    ));

要求

此参数需要Guzzle,PHP HTTP客户端

composer require guzzlehttp/guzzle

发送结果到参数

可以使用send result to参数将任务结果发送到指定的文件。

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'],
    ));

此外,您还可以使用afterfailed辅助方法。

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',
    ));

跳过参数

跳过参数可用于在 skip 参数评估为 true 时跳过任务。该参数的默认优先级为 100000,这意味着它在任何低优先级任务参数之前处理。

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 ...');

如果使用可调用对象,将把 TaskInterface::class 传递给您的回调函数。此外,您还可以请求通过传递给任务处理器的容器解析(自动装配)的任何服务。

无重叠参数

可以使用非重叠参数来防止任务重叠。

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

要求

此参数需要将 CacheInterface::class 绑定到传递给任务处理器的容器。

使用 缓存服务容器服务 的示例

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

任务处理器

TaskProcessor::class 负责处理任务。

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)

要处理到期的任务,应无限期地每分钟调用一次 processSchedule 方法。

尽管如此,您也可以创建一个符合您需求的自定义调度处理器。

查看任务结果了解更多。

控制台

您可以使用控制台服务执行以下命令。

要快速开始,请考虑使用以下两个应用程序包

否则,您需要安装控制台服务并自行设置控制台。查看运行计划任务部分以查看可能的实现。

运行命令

运行到期的任务

php app schedule:run

按其ID运行特定任务

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

列表命令

列出所有任务。

php app schedule:list

事件

可用事件

use Tobento\Service\Schedule\Event;

只需确保将事件分派器传递给调度处理器

了解更多

在没有控制台的情况下运行计划任务

运行调度处理器的另一种方法是Cron作业,每分钟运行您的schedule.php脚本。以下内容应添加到生产服务器的crontab中

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

schedule.php的示例

使用容器服务的示例

composer require tobento/service-container
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
);

致谢