Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged
merged 3 commits into from
Mar 25, 2013
Merged

Console dispatcher #7466

merged 3 commits into from
Mar 25, 2013

Conversation

fabpot
Copy link
Member

@fabpot fabpot commented Mar 24, 2013

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.

flevour and others added 2 commits March 24, 2013 09:15
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).
@fabpot
Copy link
Member Author

fabpot commented Mar 24, 2013

ping @bamarni @lsmith77

@dcsg
Copy link
Member

dcsg commented Mar 24, 2013

👍

use Symfony\Component\EventDispatcher\EventDispatcher;

/**
* Optionnally dispatches events during the life time of a command run.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: Optionally

@Swop
Copy link

Swop commented Mar 24, 2013

Yeah it would be awesome! 👍

@Koc
Copy link
Contributor

Koc commented Mar 24, 2013

Will services tagged as "cache warmer" replaced with listeners for cache:clear command?

@beberlei
Copy link
Contributor

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();
Copy link
Member

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.

@beberlei
Copy link
Contributor

@Koc that doesn't make sense imho, Cache Warming should work independent of console listeners.

@Koc
Copy link
Contributor

Koc commented Mar 24, 2013

@fabpot can we get all output as a string in terminate event?

@XWB
Copy link
Contributor

XWB commented Mar 24, 2013

👍

@marcqualie
Copy link

👍 I've been working with a few Symfony Console apps lately and this functionality would be awesome!

@fabpot
Copy link
Member Author

fabpot commented Mar 24, 2013

@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.

@lyrixx
Copy link
Member

lyrixx commented Mar 24, 2013

(I repost my comment, github hide it for now)

It could be useful to be able to not throw the exception in Application::doRunCommand ; 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.

@bamarni
Copy link
Contributor

bamarni commented Mar 24, 2013

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
Copy link
Contributor

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.

Copy link
Member

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.

@bamarni
Copy link
Contributor

bamarni commented Mar 24, 2013

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)
Copy link
Member

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

@stof
Copy link
Member

stof commented Mar 24, 2013

@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 cache:clear command should be able to be used even when you have an outdated cache as its goal is to clear it.

@stof
Copy link
Member

stof commented Mar 24, 2013

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.
Copy link
Contributor

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."

@fabpot
Copy link
Member Author

fabpot commented Mar 25, 2013

@bamarni You're right. I've removed the possibility to change the command in a console.command listener.

@fabpot
Copy link
Member Author

fabpot commented Mar 25, 2013

@lyrixx not sure how to implement that. Let's do that in another PR.

@fabpot
Copy link
Member Author

fabpot commented Mar 25, 2013

@stof @bamarni I'm aware of the possible problems with cache:clear. But we already have such issues today. When upgrading Symfony where a new parameter in the DIC is required without default value, you have the same problem. So, I propose to deal with that in another PR.

see #6519 for instance

@fabpot
Copy link
Member Author

fabpot commented Mar 25, 2013

@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).

fabpot added a commit that referenced this pull request Mar 25, 2013
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
@fabpot fabpot merged commit 4f9a55a into symfony:master Mar 25, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.