Не могу заставить работать rewieer / TaskSchedulerBundle для Symfony - PullRequest
1 голос
/ 10 июля 2019

Я пытаюсь создать центральный контроллер cron в Symfony, аналогичный тому, что делает Laravel. Я нашел этот замечательный компонент: https://github.com/rewieer/TaskSchedulerBundle, но я не могу заставить его работать.

Документация для Symfony 2, и я использую 4.3

Я пытался адаптировать то, что понял.

AppKernel.php не существует, поэтому я использовал app / config / bundles.php

Похоже на это

<?php

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

Тогда я создал свой класс задач

<?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.xml я создал service.yaml

Я добавил конфиг, предложенный в комментарии (я потерял ссылку)

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

Наконец я пытаюсь запустить

Прежде чем вы спросите, да, я изменил путь / к / проекту

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

    }

}

EDIT:

Ответ от @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);

    }

}

1 Ответ

1 голос
/ 10 июля 2019

Чтобы увидеть, что происходит, вы можете использовать команду ts:list. Есть ли в этом списке рассматриваемая команда? Тогда с вашим определением службы все в порядке, и проблема заключается в вашей задаче.

Чтобы проверить это далее, давайте проверим вашу задачу: определив $schedule->everyMinutes(5);, вы указываете, что она должна запускаться только тогда, когда текущая минута делится на пять. Так, если вы, например, запустите ts:run в 17:03, задача не будет выполнена. Если вы позвоните ts:run в 17:05, он будет выполнен. Концепция cron не сохраняет время последнего выполнения и перезапускает вашу задачу по истечении пяти минут - наоборот, если вы вызываете бегуна несколько раз в течение одной и той же минуты (например, до 17:05:59), задача также будет исполняться несколько раз.

Во время отладки может быть полезно пропустить эту часть. Не определяя расписание (оставляя это поле пустым), ваша задача будет выполняться при каждом вызове.

Кроме того, как вы проверяли, выполнялась ли задача или нет? Ваш пример кода не содержит никаких действий, которые нужно выполнить, так что вы можете по крайней мере добавить любой отладочный вывод

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...