Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

[2.2] [FrameworkBundle] Add events to console commands#3889

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
flevour wants to merge15 commits intosymfony:masterfromflevour:standard-events-cli

Conversation

@flevour
Copy link
Contributor

Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass:Build Status

Fixes the following tickets:#1929
Todo:

  • tests needed?

Copy link
Member

Choose a reason for hiding this comment

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

the code when using the shell should not be changed. Events should be dispatched by the commands launched inside the shell, not before and after running the shell itself

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Alright, I was unsure about that point. Fixed.

@flevour
Copy link
ContributorAuthor

I am bit confused here. I await some helping pointers from any core dev.
EventDispatcher yes? If no, how to do this without recreating another EventDispatcher?

Copy link
Contributor

Choose a reason for hiding this comment

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

this variable would better be named$exitCode

@lsmith77
Copy link
Contributor

i havent tested this branch, but in concept it seems good to me. please also add a test case. seeRegisterKernelListenersPassTest

@stof
Copy link
Member

@lsmith77 no need to add a test for the compiler pass as it should be removed (it duplicates things already possible with the existing pass for event listeners as it is exactly the same with a different tag)

@lsmith77
Copy link
Contributor

which "existing pass for event listeners" are you talking about?

@lsmith77
Copy link
Contributor

are you saying thatRegisterKernelListenersPass should be refactored to also handle "console" events?

@stof
Copy link
Member

@lsmith77 there isnothing to refactor. Simply register a listener with<tag name="kernel.event_listener" event="console.init" method="foo" />

@lsmith77
Copy link
Contributor

ah i see now .. since he is using$container->getDefinition('event_dispatcher'); instead of a separate event dispatcher (which would not make sense).

its maybe a bit iffy to call itkernel.event_listener now, but also not totally wrong as its just a result of the console being sort of a 2nd class citizen with our entire kernel setup.

@flevour
Copy link
ContributorAuthor

Thanks for your feedback, I'll try to work on this PR in the next few days.

@flevour
Copy link
ContributorAuthor

I applied the suggestions above.
Namely:

  • removed the CompilerPass
  • renamed $statusCode into $exitCode
  • implemented 2 Events (init and terminate) to let the programmer extend behaviour before and after command execution. I couldn't use 'ConsoleEvents::EXIT' as the 'exit' token is reserved.

Copy link
Member

Choose a reason for hiding this comment

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

you should not extend KernelEvent as KernelEvent has the request and the request type which are totally irrelevant here

@flevour
Copy link
ContributorAuthor

I probably did a bit of a mess with my last push. Do you have any more suggestions/comments to add?

Copy link
Member

Choose a reason for hiding this comment

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

you should use the short class name (the other solution would be the FQCN, i.e. with the leadaing\ but Sf2 uses the short classname everywhere). The current code will break the autocompletion is some IDE (PhpStorm would consider it asSymfony\Bundle\FrameworkBundle\Console\Event\Symfony\Component\Console\Input\InputInterface for instance)

@Seldaek
Copy link
Member

Dirty hack idea (because I enjoy that sport): before dispatching register a new autoloader that will create any class that does not exist with:

eval(<<<CODEclass$class{    public function __call($name,$args)    {    }}CODE);

That way services can be created and then called even if they don't exist anymore. It would mask any classname mistake though, so it should only be registered when the cache:clear command is called IMO.

@stof
Copy link
Member

@Seldaek running any command in the prod environment with an outdated cache would also break things

@flevour
Copy link
ContributorAuthor

I have given some thought but I still don't have any solution.
Let me recap.

When executed with --no-debug, the console application will use the currently cached kernel and container. If a listener/subscriber class gets removed (e.g.: in a deploy) the console application breaks with a fatal error, as it tries to load the event dispatcher from the cached container which in turn contains references to the not-existing-any-more class. In general all usages of the console application will break, but in particular it won't be possible to use it to clear the cache.

I can think of 3 approaches:
A. Preventive care: avoid edge cases aka fatal errors before they happen, take some countermeasures to avoid them
B. Cure the symptom: try to handle the problem when it occurs.

Here is a list of some proposals:
A

  1. implement a compiler pass to store any listener/subscriber class name in a container parameter as an array. The console application or the cache clear command, will loop through this parameter and check the existence of each element
  2. create a class ParanoidEventDispatcher which dynamically extends from %event_dispatcher.class% in order to add our own logic to the addListener/addSubscriber methods (note that it's not possible to wrap the EventDispatcher as the fatal error happens on its instantiation) and implement a compiler pass to inject the new ParanoidEventDispatcher in place of the original one.
  3. implement a new event dispatcher ParanoidEventDispatcher with the needed fixes in addListener/addSubscriber methods, make it available as a service and use it instead of the event_dispatcher service. Duplicating the logic contained in RegisterKernelListenersPass in order to attach to this new service the same listeners and subscribers of event_dispatcher.
  4. force a rm -rf before cache:clear execution
    B
  5. @Seldaek solution
  6. some creepy shutdown function to handle the fatal error and give hints to the user

I don't like any of these proposals, but if I really I had to choose, my order of choice would be A3, A1, A2.

@stof
Copy link
Member

The cache:clear command cannot be responsible to check the instantiation of the dispatcher as the dispatcher is sued before calling the command.

@flevour
Copy link
ContributorAuthor

@stof I assume you are commenting on A4. Yes, the code for rm -rf would need to be in the Application not in the CacheClearCommand itself.

@Seldaek
Copy link
Member

IMO the only command that matters for the issue of "listener classes
gone" if cache:clear, if it's called maybe the events should just not be
triggered at all, or you should implement one of those hacks.

It's the same with the routing, annotations and whatever else is in the
cache, if you remove the class and you don't clear your cache in prod
environment you will have weird bugs where the framework goes further
than it should before blowing up on a missing class.

It is a predicate of the framework that if you change the code, you
should clear your prod cache before deploying, so IMO it's ok to have
that problem for other commands. But the cache:clear command must work
at all costs (including dropping listeners, maybe while outputting a
warning), because that's the way many people will use to clear/warmup
their cache.

@flevour
Copy link
ContributorAuthor

One other (very crazy) idea could be:

A5: also cache (aka copy) the event listeners/subscribers classes and all their dependencies and configure the autoloader accordingly. Even if it's probably more hassle than it's worth, It would make some sense as a cache works only as long as all the classes it depends on still exist. The extreme result of this path is we end up caching the whole application, but if we apply this only in the case of cache:clear dependencies, it might be not as bad.

Going back to a more traditional thinking, A3 (implement a new dispatcher) might be the cleanest/easiest solution to offer console events and at the same provide useful output should something break during cache:clear.

Please share your opinions and suggestions so I can get this PR moving again!

@bamarni
Copy link
Contributor

How about a flag on the command, just like theisEnabled method, there could be anisSilent method defaulting to false, and when set to true (eg. cache:clear command) the Application wouldn't dispatch any event?

@bamarni
Copy link
Contributor

@flevour : I've continued your PR with this commit :bamarni/symfony@3072ee3

Are you fine with this implementation? I've not tested it yet but it should give you an idea about what I meant.

Unfortunately I can't submit a PR against your fork as github doesn't show it to me in the available symfony forks list. Maybe you can cherry-pick it?

@bamarni
Copy link
Contributor

@flevour : did you had time to look at my commit? It should fix the issue, I guess now it only misses some small tweaks and unit tests.

If you don't have time to devote on this, I'd be happy to help you to sort this out by opening another PR, but of course I'll squash the commits with your name so that you keep the authorship for this feature!

@dlsniper
Copy link
Contributor

@fabpot what about this? It's also needed forsymfony/swiftmailer-bundle#23
Should this be rescheduled for 2.3?

@fabpot
Copy link
Member

Closing in favor of#6124

@fabpotfabpot closed thisMar 23, 2013
fabpot pushed a commit to fabpot/symfony that referenced this pull requestMar 24, 2013
This adds an init and terminate event for commands. They aredispatched from ContainerAwareCommand.The cache:clear command can't implement this (cf.symfony#3889 on Github).
@fabpotfabpot mentioned this pull requestMar 24, 2013
fabpot added a commit that referenced this pull requestMar 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#2352refs#1884,#1929This 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 events4edf29d added helperSet to console event objectsf224102 Added events for CLI commands
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

8 participants

@flevour@lsmith77@stof@travisbot@Seldaek@bamarni@dlsniper@fabpot

[8]ページ先頭

©2009-2025 Movatter.jp