Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Console] Commands aren't able to fully gracefully exit by themselves #47809

Copy link
Copy link
Closed
@lcobucci

Description

@lcobucci
Issue body actions

Symfony version(s) affected

5.2.0+

Description

Since df57119 symfony/console is reacting to signals, dispatching events, and exiting right away.

My main issue here is the exit() inside of the signal handler, as it imposes a specific application design for graceful shutdowns and prevents the dispatch of console.terminate event.

How to reproduce

A command like this should suffice:

<?php

declare(strict_types=1);

namespace MyApp;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\SignalableCommandInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

use function sleep;
use const SIGINT;
use const SIGTERM;

#[AsCommand('testing')]
final class Testing extends Command implements SignalableCommandInterface
{
    private bool $shouldContinue = true;

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        while ($this->shouldContinue) {
            $output->writeln('Still processing...');
            sleep(1);
        }

        $output->writeln('Wrapping up, wait a sec...'); // this message is never shown (unless we remove the `exit()` call)

        return self::SUCCESS;
    }

    public function getSubscribedSignals(): array
    {
        return [SIGINT, SIGTERM];
    }

    public function handleSignal(int $signal): void
    {
        $this->shouldContinue = false;
    }
}

Possible Solution

I believe Symfony should not auto exit on that situation or at least provide a way to skip it.

Additional Context

Execution of the sample command with the exit():

$ bin/console testing
{"message":"Notified event \"console.command\" to listener \"Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener::configure\".","context":{"event":"console.command","listener":"Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener::configure"},"channel":"event","severity":"DEBUG","timestamp":"2022-10-07T10:12:24.056+00:00"}
{"message":"Notified event \"console.command\" to listener \"Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler::onCommand\".","context":{"event":"console.command","listener":"Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler::onCommand"},"channel":"event","severity":"DEBUG","timestamp":"2022-10-07T10:12:24.056+00:00"}
Still processing...
Still processing...
Still processing...
Still processing...
^C $ 

Execution of the sample command without the exit():

$ bin/console testing
{"message":"Notified event \"console.command\" to listener \"Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener::configure\".","context":{"event":"console.command","listener":"Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener::configure"},"channel":"event","severity":"DEBUG","timestamp":"2022-10-07T10:13:39.000+00:00"}
{"message":"Notified event \"console.command\" to listener \"Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler::onCommand\".","context":{"event":"console.command","listener":"Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler::onCommand"},"channel":"event","severity":"DEBUG","timestamp":"2022-10-07T10:13:39.000+00:00"}
Still processing...
Still processing...
Still processing...
^CWrapping up, wait a sec...
{"message":"Notified event \"console.terminate\" to listener \"Symfony\\Component\\Console\\EventListener\\ErrorListener::onConsoleTerminate\".","context":{"event":"console.terminate","listener":"Symfony\\Component\\Console\\EventListener\\ErrorListener::onConsoleTerminate"},"channel":"event","severity":"DEBUG","timestamp":"2022-10-07T10:13:41.554+00:00"}
{"message":"Notified event \"console.terminate\" to listener \"Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler::onTerminate\".","context":{"event":"console.terminate","listener":"Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler::onTerminate"},"channel":"event","severity":"DEBUG","timestamp":"2022-10-07T10:13:41.554+00:00"}
$

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.