-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Console dispatcher #7466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Console dispatcher #7466
Conversation
This adds an init and terminate event for commands. They are dispatched from ContainerAwareCommand. The cache:clear command can't implement this (cf. symfony#3889 on Github).
👍 |
use Symfony\Component\EventDispatcher\EventDispatcher; | ||
|
||
/** | ||
* Optionnally dispatches events during the life time of a command run. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: Optionally
Yeah it would be awesome! 👍 |
Will services tagged as "cache warmer" replaced with listeners for cache:clear command? |
best way to introduce this feature by a longshot without changing existing code, +1 from me. |
$event = new ConsoleForExceptionEvent($command, $input, $output, $e, $event->getExitCode()); | ||
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); | ||
|
||
throw $event->getException(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be useful to be able to not throw the exception ; like in the HttpKernel.
Use case : you have a long running process like a rabbitmq consumer. With this feature, we could delegate the exception process into a dedicated event listener and make the "raw" command cleaner.
@Koc that doesn't make sense imho, Cache Warming should work independent of console listeners. |
@fabpot can we get all output as a string in terminate event? |
👍 |
👍 I've been working with a few Symfony Console apps lately and this functionality would be awesome! |
@Koc: you can wrap/change the output instance in the command event, so that you can then get what was displayed in the terminate event. This PR gives you the flexibility, it's then up to you to use it the way you want. |
(I repost my comment, github hide it for now) It could be useful to be able to not throw the exception in Use case : you have a long running process like a rabbitmq consumer. With this feature, we could delegate the exception process into a dedicated event listener and make the "raw" command cleaner. |
good to see this moving forward 👍 @stof had previously spotted a bug with this feature and the cache:clear command, see (#3889 (comment) for the beginning of the discussion), basically we came out to the conclusion that the cache:clear command shouldn't have this event dispatching capability, otherwise it would require some dirty hacks, do you think it will be easily doable when integrating this to the framework (as I can see this PR is only about the component part)? |
* | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
class ConsoleForExceptionEvent extends ConsoleEvent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "For"? "ConsoleExceptionEvent" seems more consistent with the other ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabpot did you just miss this? I don't understand the class name either.
I'd also have a remark about the ability to change the command to be executed through the pre-event, do you have any use case in mind? Imo this doesn't make so much sense. I can see it'd use the same input object, It means that the changed command should have the same arguments / options than the first one, or basically that it should be able to work with the same input, it looks like a pretty restricting condition. It is also not always so easy to instantiate a command object, for example when using this feature with the framework, one would always need to have the container so that it can passes it to the command (as usually they are container aware), it looks like all this would be kind of a "sub-application". |
@@ -80,6 +85,11 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') | |||
} | |||
} | |||
|
|||
public function setDispatcher(EventDispatcher $dispatcher) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the typehint should be the interface
@fabpot Would you use the same listener than for the kernel when integrating it in a Sf2 project ? Because in this case, we would face the bug I reported in the previous PR: if you deleted a subscriber class and the kernel is in non-debug mode, creating the event dispatcher object will break (in debug mode, the container would be refreshed without the subscriber). But the |
otherwise, 👍 for this implementation. Should the listener flushing the swiftmailer memory spool be added in the bridge in this PR or in a subsequent one ? |
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
/** | ||
* Allows to do things before the command is executed or to change the command to execute altogether. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not correct English grammar. I don't think the 3rd person verb fits here as a class description. You probably want something more like "Event object for pre-execution changes. \n\n Listeners may take actions before the command is executed, including changing the command to execute."
@bamarni You're right. I've removed the possibility to change the command in a console.command listener. |
@lyrixx not sure how to implement that. Let's do that in another PR. |
@stof The Swiftmailer listener should be done in another PR, especially because it is not that easy (the best would be do be able to move the listener from the bundle to the bridge). |
This PR was merged into the master branch. Discussion ---------- Console dispatcher | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #3889, #6124 | License | MIT | Doc PR | symfony/symfony-docs#2352 refs #1884, #1929 This is an alternative implementation for adding events to console applications. This implementation has the following features: * Available for anyone using the Console component and it is not tied to FrameworkBundle (this is important as one thing we are trying to solve is email sending from a command, and frameworks like Silex using the Console component needs a solution too); * Non-intrusive as the current code has not been changed (except for renaming an internal variable that was wrongly named -- so that's not strictly needed for this PR) * The new DispatchableApplication class also works without a dispatcher, falling back to the regular behavior. That makes easy to create applications that can benefit from a dispatcher when available, but can still work otherwise. * Besides the *before* and *after* events, there is also an *exception* event that is dispatched whenever an exception is thrown. * Each event is quite powerful and can manipulate the input, the output, but also the command to be executed. Commits ------- 4f9a55a refactored the implementation of how a console application can handle events 4edf29d added helperSet to console event objects f224102 Added events for CLI commands
refs #1884, #1929
This is an alternative implementation for adding events to console applications.
This implementation has the following features:
FrameworkBundle (this is important as one thing we are trying to solve is
email sending from a command, and frameworks like Silex using the Console
component needs a solution too);
an internal variable that was wrongly named -- so that's not strictly needed
for this PR)
falling back to the regular behavior. That makes easy to create applications
that can benefit from a dispatcher when available, but can still work
otherwise.
that is dispatched whenever an exception is thrown.
also the command to be executed.