define and call standard events for CLI commands #1929

Closed
lsmith77 opened this Issue Aug 10, 2011 · 14 comments

Projects

None yet

5 participants

@lsmith77
Collaborator

the idea is to create an equivalent to the kernel events like request, controller, view, response.

this would allow doing common dynamic setup tasks (like doing some dynamic configuration inside a storage API). but it maybe we also want to have additional events fired in other cases, like when an uncaught exception happens or to maintain an audit log of CLI command calls.

my personal example use case is wanting to set a dynamic HTTP header in all commands calling a backend through a load balancer that picks the server based on said HTTP header.

see also #1884 for why a tag and not an event listener

@stof
Member
stof commented Apr 4, 2012

@lsmith77 any news about this ?

@lsmith77
Collaborator
lsmith77 commented Apr 4, 2012

havent had time for this. but should be something for someone who wants to dip their toes in core dev. will try to find a helping hand via twitter.

@cordoval
cordoval commented Apr 4, 2012

@lsmith sounds interesting taking a look

@cordoval
cordoval commented Apr 5, 2012

@lsmith77 can you please elaborate on

my personal example use case is wanting to set a dynamic HTTP header in all commands calling a backend through a load balancer that picks the server based on said HTTP header.

I am also confused because in the other ticket you said tags, @fabpot reopened it because of it otherwise he would have kept it closed and now this is events again.

@lsmith77
Collaborator
lsmith77 commented Apr 5, 2012

here is an example of a kernel listener, that i would also like to run on the CLI before any command is executed:

    api.jackalopeheader.listener:
        class: Foo\BarBundle\EventListener\JackalopeHeaderListener
        arguments:
            - @doctrine_phpcr.odm.document_manager
            - %phpcr_loadbalancer_session_header%
            - %phpcr_loadbalancer_session_max_value%
        tags:
            -  { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

so the idea would be that I could also modify the tag section to something like the following

        tags:
            -  { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
            -  { name: cli.event_listener, event: cli.init, method: onCliInit }
@stof
Member
stof commented Apr 5, 2012

@lsmith77 if you implement it using the EventDispatcher, there is no reason to have a different tag name.

@flevour
flevour commented Apr 10, 2012

Any progress on this? May I give it a try using the tag approach?

@lsmith77
Collaborator

@flevour i have not worked on it .. and i have not seen anyone else post any progress on this ticket

@flevour
flevour commented Apr 10, 2012

@lsmith77 if the tag approach is still the way to go, I'll give it a shot.

@lsmith77
Collaborator

yes it is.

@flevour
flevour commented Apr 10, 2012

Sorry, but I need to discuss this a little further. Where would the fix go?

I read #1884 a 3 or 4 times to make sure I am understanding the issue.
In that case the point for not using EventDispatcher was to avoid making the Console component depend on it. So the solution was to implement some code inside the CacheClearCommand and using the tag system to call all tagged services at the right moment. Anyway depending on the EventDispatcher wouldn't be a problem because the CacheClearCommand is implemented inside FrameworkBundle which depends on the ED (is this statement correct at all?).

If I understand correctly, the scope of this issue is a bit larger. It's not aiming to solve a specific use case, as in the cache:clear scenario. Instead it's aiming to create a way to solve all possible cases when you want to call a set of services before or after the execution of a command. This would mean calling all properly tagged services at the right moment. That is, modifying ContainerAwareCommand in order to wrap the call to execute() with calls to the tagged services.

As this sounds very EventDispatcher-y to me (and your example makes the parallelism even more likely), could you please help me understand why going with tagged services is the way to go and how would you implement it?

@lsmith77
Collaborator

The final code would be in the FrameworkBundle as a new compiler pass. There we would look for the tagged services and connect them to events. The events should themselves be triggered inside Symfony\Bundle\FrameworkBundle\Console\Application

@flevour
flevour commented Apr 11, 2012

I published the PR just to gather feedback about the direction I am taking.
I tried to avoid using EventDispatcher but eventually I would end up rewriting a worse implementation of it for this use case.

@flevour
flevour commented Apr 14, 2012

Hi Lukas, when you have 2 mins, please give a look at #3889, I need some pointers to move on.

@fabpot fabpot added a commit that referenced this issue Mar 25, 2013
@fabpot fabpot merged branch fabpot/console-dispatcher (PR #7466)
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
c1bd3b5
@fabpot fabpot closed this Mar 25, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment