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] ConsoleEvents::SIGNAL subscriber not called #45332

Copy link
Copy link
Closed
@GwendolenLynch

Description

@GwendolenLynch
Issue body actions

Symfony version(s) affected

5.2+

Description

The (awesome) console signal handling introduced in #33729 and #37827 seems to have some issues (or maybe it's just me 😺 ) with subscriber events:

  • Subscriber ConsoleEvents::SIGNAL events do not get called, but events such as ConsoleEvents::TERMINATE do
  • Listener events (command implementing SignalableCommandInterface) work, with one caveat;
    • if a subscriber exists, it will be called and the command's discrete handler ignored

How to reproduce

  1. Create a Symfony project symfony new --webapp symfony-pcntl-test

  2. Build the following classes

// src/Command/AbstractSignalCommand.php

abstract class AbstractSignalCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title("Starting {$this->getName()} command execution");

        for ($i = 0; $i <10; ++$i) {
            $io->writeln('Tick ' . $i);
            sleep(1);
        }

        $io->success('Normal exit from command.');

        return Command::SUCCESS;
    }
}
// src/Command/SignalListenerCommand.php

#[AsCommand(
    name: 'app:signal:listener',
)]
class SignalListenerCommand extends AbstractSignalCommand implements SignalableCommandInterface
{
    public function getSubscribedSignals(): array
    {
        return [SIGINT];
    }

    public function handleSignal(int $signal): void
    {
        if (SIGINT === $signal) {
            dump('Caught a listener SIGINT');
            exit;
        }
    }
}
// src/Command/SignalSubscriberCommand.php

#[AsCommand(
    name: 'app:signal:subscriber',
)]
class SignalSubscriberCommand extends AbstractSignalCommand
{
}
// src/EventSubscriber/CommandSignalSubscriber.php

class CommandSignalSubscriber implements EventSubscriberInterface
{
    public function onConsoleSignal(ConsoleSignalEvent $event): void
    {
        if ($event->getHandlingSignal() === SIGINT) {
            dump('Caught a !!!subscriber!!! SIGINT');
            exit;
        }
    }

    public function onConsoleTerminate(ConsoleTerminateEvent $event)
    {
        dump('Handling normal termination event');
    }

    public static function getSubscribedEvents(): array
    {
        return [
            ConsoleEvents::SIGNAL => 'onConsoleSignal',
            ConsoleEvents::TERMINATE => 'onConsoleTerminate',
        ];
    }
}
  1. Check event dispatcher
$ bin/console debug:event-dispatcher console.signal
# ...
 ------- ---------------------------------------------------------------- ---------- 
  Order   Callable                                                         Priority  
 ------- ---------------------------------------------------------------- ---------- 
  #1      App\EventSubscriber\CommandSignalSubscriber::onConsoleSignal()   0         
 ------- ---------------------------------------------------------------- -----------
  1. Run the listener enabled command and emit a CTRL+c
$ bin/console app:signal:listener

Starting app:signal:listener command execution
==============================================

Tick 0
Tick 1
^C"Caught a !!!subscriber!!! SIGINT"

NOTE: The handling of the signal is done in the subscriber here, but removing ConsoleEvents::SIGNAL from CommandSignalSubscriber::getSubscribedEvents will cause the handling to be done by the listener.

  1. Run the subscriber enabled command and emit a CTRL+c
$ bin/console app:signal:subscriber

Starting app:signal:subscriber command execution
================================================

Tick 0
Tick 1
^C

NOTE: Nothing handles the signal.

Possible Solution

No response

Additional Context

  • Tested on Symfony v6.0.4

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.