Maison  >  Article  >  développement back-end  >  Débogage interactif avec Symfony Console

Débogage interactif avec Symfony Console

WBOY
WBOYoriginal
2024-07-20 22:46:011097parcourir

Interactive debugging with Symfony Console

L'un des systèmes les plus importants dont nous disposons chez RoundingWell est le moteur d'évaluation, ou « évaluations » comme nous l'appelons généralement. Ce système est responsable du traitement des écouteurs d'événements configurés spécifiques au client, ce qui nous permet de fournir une expérience utilisateur très unique pour chaque organisation. Inutile de dire que ce système est extrêmement important pour notre application et qu'il est essentiel de pouvoir savoir exactement ce qu'il a fait, ou fera, pour un événement donné.

Aujourd'hui, je travaillais sur la transition d'un de nos clients de certains événements existants vers des événements plus récents et je devais m'assurer que l'une des étapes traitait correctement l'événement. Nous effectuons beaucoup de journaux autour des évaluations, et je savais que les informations dont j'avais besoin se trouvaient dans les journaux. Mais le problème avec beaucoup de journaux est qu’il y a beaucoup de journaux. De plus, il me suffisait d'exécuter la première partie de chaque déclencheur pour vérifier que la migration fonctionnait.

Je me suis dit : "Ne serait-il pas intelligent si nous pouvions avoir un débogueur d'étape de type Xdebug pour le moteur d'évaluation ? Je sais que Symfony Console a toutes les fonctionnalités dont j'ai besoin pour cela..."

Et c’est exactement ce que j’ai fait. Parce que notre application est entièrement injectée de dépendances, j'ai pu créer une nouvelle classe pour envelopper StepFactory, qui est responsable de la lecture de la configuration et de la création des "étapes" qui composent l'évaluation.

use RoundingWell\Framework\DebugVar;
use RuntimeException;
use Symfony\Component\Console\Style\SymfonyStyle;

readonly class StepFactoryWithConsoleConfirmation implements StepFactory
{
    public function __construct(
        private StepFactory $stepFactory,
        private SymfonyStyle $style,
        private bool $confirmCreatedStep = true,
        private bool $showCreatedStep = true,
        private bool $showStepDefinition = false,
    ) {
    }

    public function create(object $subject, StepDefinition $definition): Step
    {
        if ($this->showStepDefinition) {
            $debug = new DebugVar($definition->parameters);

            $this->style->info(
                message: <<<TEXT
                Next step is $definition->name with parameters:

                $debug
                TEXT,
            );
        }

        $step = $this->stepFactory->create($subject, $definition);

        if ($this->showCreatedStep) {
            $debug = new DebugVar($step);

            $this->style->info(
                message: <<<TEXT
                Step $definition->name created as:

                $debug
                TEXT,
            );
        }

        if ($this->confirmCreatedStep && ! $this->style->confirm(question: "Continue with evaluation?")) {
            throw new RuntimeException(
                message: "Evaluation aborted at step {$definition->name}",
            );
        }

        return $step;
    }
}

Et, avec un peu de manipulation de conteneur dans ma commande console, nous avons un débogueur d'évaluation interactif :

use DI\Container;
use RoundingWell\Common\Command\CommandBus;
use RoundingWell\Common\Command\CommandBusComposed;
use RoundingWell\Common\Command\Middleware\LoggingMiddleware;
use RoundingWell\Evaluation\Command\EvaluateEvent;
use RoundingWell\Evaluation\Command\EvaluateEventHandler;
use RoundingWell\Evaluation\Step\StepFactory;
use RoundingWell\Evaluation\Step\StepFactoryWithConsoleConfirmation;
use Symfony\Component\Console\Style\SymfonyStyle;

readonly class EvaluationDebug
{
    public function __construct(
        private Container $container,
    ) {
    }

    public function __invoke(
        SymfonyStyle $symfonyStyle,
        string $eventType,
        string $eventId,
        string|null $evaluationId = null,
    ): void {
        // The command bus MUST ONLY log executed commands.
        $commandBus = new CommandBusComposed(
            $this->container->get(LoggingMiddleware::class),
        );

        // The step factory MUST be wrapped to step through the evaluation.
        $stepFactory = new StepFactoryWithConsoleConfirmation(
            stepFactory: $this->container->get(StepFactory::class),
            style: $symfonyStyle,
        );

        $this->container->set(CommandBus::class, $commandBus);
        $this->container->set(StepFactory::class, $stepFactory);

        $command = new EvaluateEvent(
            eventClass: $eventType,
            eventId: $eventId,
            evaluationId: $evaluationId,
        );

        $this->container->get(EvaluateEventHandler::class)->handle($command);

        $symfonyStyle->success('Evaluation complete');
    }
}

C'est tout pour aujourd'hui !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn