我无法为 Symfony 工作制作 rewieer/TaskSchedulerBundle

I can not make rewieer/TaskSchedulerBundle for Symfony work

我正在尝试在 Symfony 中创建一个中央 cron 控制器,类似于 Laravel 所做的。我找到了这个很棒的组件:https://github.com/rewieer/TaskSchedulerBundle 但我无法让它工作。

该文档适用于 Symfony 2,我使用的是 4.3

我试着调整我的理解。

没有AppKernel.php 所以我用了app/config/bundles.php

看起来像这样

<?php

return [
    ...
    Rewieer\TaskSchedulerBundle\RewieerTaskSchedulerBundle::class => ['all' => true],
];

然后我创建了我的任务class

<?php

namespace App\Tasks;

use Rewieer\TaskSchedulerBundle\Task\AbstractScheduledTask;
use Rewieer\TaskSchedulerBundle\Task\Schedule;

class UpdateDFsize extends AbstractScheduledTask {

    /**
     * Set the Cron Schedule
     *
     * @param Schedule $schedule
     */
    protected function initialize(Schedule $schedule) {
        $schedule
            ->everyMinutes(5); // Perform the task every 5 minutes
    }

    /**
     * Run Update DFsize cron
     *
     * @return string|null  result of the cron or null if fails
     */
    public function run() : ?string {
        //Do some stuff
        return $result;
    }

}

我创建了一个 service.yaml

而不是使用 service.xml

我添加了评论中建议的配置(我丢失了 link)

parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    #Added per recommendation
    **_instanceof:
        Rewieer\TaskSchedulerBundle\Task\TaskInterface:
            tags: ['ts.task']

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

最后我尝试运行

在你问之前,是的,我修改了path/to/project

php /path/to/project/bin/console ts:run >> /dev/null 2>&1

但是没有任何反应,我在控制台中没有任何反应,我不知道如何使用 xdebugger+phpstorm

进行调试

任何建议将不胜感激。

为了测试我的 cron,我创建了一个控制器

至此,我确认代码是正确的

<?php

namespace App\Controller;

use App\Tasks\UpdateDFsize;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class CronController
{

    public function __construct() {
    }

    /**
     * @Route("/cron/dfsize", name="index")
     * @param UpdateDFsize $updateDFsize
     * @return Response
     */
    public function updateDFsize(UpdateDFsize $updateDFsize) : Response {

        $response = $updateDFsize->run();
        return new Response($response, Response::HTTP_OK);

    }

}

编辑:

@NicoHaase 的回答非常合适。但是,我需要在外部执行 cron 控制器,所以我遵循了这个 Symfony 文档 https://symfony.com/doc/current/console/command_in_controller.html 并修改了我的控制器以供外部访问

<?php

namespace App\Controller;
use http\Exception;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;

class CronController
{

    /**
     * @Route("/cron", name="cron")
     * @param KernelInterface $kernel
     * @return Response
     * @throws \Exception
     */
    public function runCron(KernelInterface $kernel) : Response {

        $application = new Application($kernel);
        $application->setAutoExit(false);

        //Run the command
        $input = new ArrayInput([
            'command' => 'ts:run',
        ]);

        //Prepare output
        $output = new BufferedOutput();
        $application->run($input, $output);
        $content = $output->fetch();


        return new Response($content);

    }

}

要查看发生了什么,可以使用命令ts:list。这是否列出了有问题的命令?那你的服务定义没问题,问题出在你的任务上

为了进一步检查这一点,让我们检查一下您的任务:通过定义 $schedule->everyMinutes(5);,您指定当当前分钟可以被五整除时它应该只 运行。因此,如果您在 17:03 上 运行 ts:run,任务将不会执行。如果您在 17:05 上调用 ts:run,它将执行。 cron 概念不会保存上次执行时间并在五分钟后重新运行 你的任务 - 反过来,如果你在同一分钟内多次调用 运行ner(所以在 17:05:59),任务也会执行多次

调试时,跳过这部分可能会有帮助。通过不定义任何时间表(通过将其留空),您的任务将在每次调用时 运行。

另外,你是如何检查任务是否运行的?您的示例代码不包含任何要 运行 的操作,因此您至少可以添加任何调试输出