Updated: Comment 0
Problem/Motivation
Currently we do have a couple of container aware services which provided $container as well as setContainer().
Proposed resolution
If you value uniformity in core then when should either extend a class with ContainerAware or use its corresponding trait ( ContainerAwareTrait )
/**
* Attaches access check services to routes and runs them on request.
*
* @see \Drupal\Tests\Core\Access\AccessManagerTest
*/
class AccessManager extends ContainerAware {
/**
ControllerResolver.php is an example which proves the point that ContainerAwareTrait should be used in preference to extending ContainerAware.
class ControllerResolver extends BaseControllerResolver implements ControllerResolverInterface {
/**
* The injection container that should be injected into all controllers.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
and need to become
class ControllerResolver extends BaseControllerResolver implements ControllerResolverInterface {
use ContainerAwareTrait;
tim.plunkett and msonnabaum have raised valid concerns in #19 and #20
So the use of ContainerAwareTrait should be limited in scope to where dynamically changing the container might be a useful thing.
If the object can't function at all without the container, it should use constructor injection.
Remaining tasks
User interface changes
API changes
Comment | File | Size | Author |
---|---|---|---|
#55 | 2229183-apache-crash-ff.png | 20.87 KB | plach |
#55 | 2229183-apache-crash-chrome.png | 12.4 KB | plach |
#49 | interdiff-46.49.txt | 773 bytes | martin107 |
#49 | container_aware_trait-2229183-49.patch | 24.26 KB | martin107 |
#46 | container_aware_trait-2229183-46.patch | 24.37 KB | martin107 |
Comments
Comment #1
martin107 CreditAttribution: martin107 commented@dawehner - Just before I jump on this and get ahead of myself.
Are you saying the template to follow should be :-
From core_servies.yml
and this is an example of what needs to change ?
Comment #2
dawehnerThe @setContainer would stay and the second example would use setter injection.
Comment #3
martin107 CreditAttribution: martin107 commentedFirst Pass .. I hope I have them all...
With this patch drupal installs .. which shows a lot of functionality .. lets see what testbot has to say.
Comment #5
dawehnercan't we use the trait all over the place?
Comment #6
martin107 CreditAttribution: martin107 commented1) Removed all instances of "extends ContainerAware" in favour of "use ContainerAwareTrait"
2) For style and layout perspective using BrokenHandlerTrait as found in core as the template.. so removed fully qualified use of
"use \Symfony\Component\DependencyInjection\ContainerAwareTrait;"
3) most of the failing tests seem to come from DrupalUnitTest.php and is construction of KeyValueFactory, its constructor now need only a
single parameter and a set to inject the service_container.
Comment #7
martin107 CreditAttribution: martin107 commentedComment #9
martin107 CreditAttribution: martin107 commentedNow using AddMethodCall to inject the service_continaer correctly. Fixed in two other places.
Comment #11
martin107 CreditAttribution: martin107 commentedFixed malformed AddMethodCall
Comment #13
martin107 CreditAttribution: martin107 commentedFixed more tests.
Comment #15
martin107 CreditAttribution: martin107 commentedFixed a few more tests
CacheContextsTest and HttpKernelTest
Comment #16
martin107 CreditAttribution: martin107 commentedComment #17
dawehnerOh I would not have expected that this issue is so much effort.
Thank you!
Comment #19
msonnabaum CreditAttribution: msonnabaum commentedI don't think we should be making these classes use ContainerAware if they aren't already. Really, i don't understand why we're doing it at all. Why not just inject it in the constructor like KeyValueFactory does? If the object can't function at all without the container, it should use constructor injection.
From what I can tell, there isn't a scenario where setContainer is called again, so all this seems to be gaining us is a more cumbersome service definition.
Comment #20
tim.plunkettYeah I think replacing "extends ContainerAware" is about all we should do here. Any services using proper injection can be left alone.
Comment #21
martin107 CreditAttribution: martin107 commentedForgive me if I am 'Tilting at windmills"
I accept this is a minor, subtle point, but forcing me to make the case for using ContainerAwareTrait vs "extends ContainerAware" is no bad thing!
So I have updated the issue summary
In the next patch I will back out the changes unless in fits with only changing existing extended ContainerAware classes.
Comment #22
martin107 CreditAttribution: martin107 commented1) I have backed out CacheContext, KeyValueFactory and KeyValueFactoryExpirable. Lets see what the tesbot reports now.
2) I have also addressed a couple of cascaded bug each hiding each other in ThemeTestSubscriber - which incorrectly extended ContainerAware
ThemeTestSubscriber does not need a service_container it needs an IntrospectableContainer.
In any event theme_test.services.yml does not as expected inject a container of any form
The place where the uninitialised container is used is "unreached code" by the testbot hence no bug is picked up!
Since there is no need to dynamically inject a container into this class I have just added a todo in the constructor and removed the extends ContainerAware
If the testbot does not report a fail in this department I will file a separate bug report.
Comment #23
martin107 CreditAttribution: martin107 commentedComment #24
martin107 CreditAttribution: martin107 commentedResubmitting
Comment #26
martin107 CreditAttribution: martin107 commentedOk that blew up badly because of a failure to backout changes to KeyValueFactory that affected every unit test ( DrupalUnitTestBase)
Fixed
Comment #27
martin107 CreditAttribution: martin107 commentedComment #29
martin107 CreditAttribution: martin107 commentedthis should get back to the 70 fails of #15
Comment #31
martin107 CreditAttribution: martin107 commentedThis next patch is a test to prove a point ( it is not core quality code )
There is a another difference between "use ContainerAwareTrait" and "extends ContainerAware"
Only when using extends does it inherit "implements ContainerAwareInterface".
The bug I think I can see is that the controllerResolver picks up on this and at the appropriate time calls setContainer
This is the temporary change I have made to see if it resolves all the remaining issues.
Once again this change is just to highlight the issue not to solve it...
So I expect a division into two camps
To the "This issue is just needless fiddling" camp -- I think it strengthens your point.
To the "I like everything to be explicit when constructing my class" the fact that every class that may pass through ControllerResolver needs to be altered to explicitly add "implements ContainerAwareInterface" then this is a good thing...
Meh - I myself have no opinion...
Comment #32
martin107 CreditAttribution: martin107 commentedComment #33
tstoecklerYes, we should definitely add "implements ContainerAwareInterface" to all of the classes using the trait.
Comment #34
martin107 CreditAttribution: martin107 commentedReverted #31, implemented #33 If this stays green, I will add what I expect to be the template for class definition, service build instructions and factory construction of containerAware classes to the issue summary.
and then leave it for review.
Comment #35
martin107 CreditAttribution: martin107 commentedComment #36
tstoecklerPatch looks great now, thanks!
I have a couple of points, that are very minor, but since isn't blocking anything we should fix them before commit I think.
Also you re-introduced the change of moving a lot of classes from constructor injection to setter injection for the container. I personally think it makes a lot of sense to consistently use setter injection in case, but there were some people that had reservations against that above. So maybe just leave that part out, so this doesn't get held up any longer?
And elsewhere: There should be an empty line between these two.
While we're at it, can we move the curly brace "{" on the same line as the "class" declaration, please?
Comment #37
dawehner@martin107
Great battle against the bot!
This is instance is certainly special for various reasons:
Comment #38
martin107 CreditAttribution: martin107 commentedThank you gentleman for your comments...
So my task from 36 was to revert every case where I mangled the constructor and converted from constructor dependency injection to setter injection....
The changes in 37 affect every instance of that... so if I have analysed the situation correctly there is nothing more for me to do.
So onto the cosmetic changes...
regarding
versus
I went looking for the definitive way forward here https://drupal.org/coding-standards
but could not find anything helpful.
I have copied the implicit standard, which is that in the very limited example of traits in core, currently,
the traits hugs the class definition...(see BrokenHandlerTait )
Can I humbly suggest that the uniform styling of traits is best done in a separate issue. Where more eyes will see it.
So that leaves #36.2 - ok no problem.
Minor Housekeeping
1) I have just been reading around the issue and just seen some of the policy discussions, and feels like I may have just blindly stepped on a landmine...I am linking here to prevent any new visitors from doing something similar
2) Linking to the bug that this issue discovered.
Comment #39
dawehner@martin107
The way to move forward is to use something sane in several issues and you have implemented a "standard" by that.
Comment #40
martin107 CreditAttribution: martin107 commentedless hugging, more sanity
Comment #41
dawehnerYeah, let's do work to undo work to add more work later.
Comment #42
dawehnerBut yeah I don't care at all tbh.
Comment #43
tstoecklerThe class whitespace stuff is documented here: https://drupal.org/node/608152#indenting
...that means BrokenHandlerTrait is doing it wrong, not a biggie though.
Thanks for updating the patch nevertheless @martin107!
Since @dawehner agrees, being bold and marking RTBC. (Nice trick in the services.yml btw!)
Edit: crosspost
Comment #44
tim.plunkettComment #46
martin107 CreditAttribution: martin107 commentedReroll.
Comment #47
martin107 CreditAttribution: martin107 commentedReroll was trivial, nothing has changed -- so back to RTBC
Comment #48
alexpottThis code looks unnecessary.
Comment #49
martin107 CreditAttribution: martin107 commentedRemoved __construct
Comment #50
dawehnerBack to RTBC
Comment #51
alexpottCommitted 12b53d0 and pushed to 8.x. Thanks!
Comment #52
alexpottLooks like https://drupal.org/node/1937056 could do with an update.
Comment #54
martin107 CreditAttribution: martin107 commented#52 change record updated
Comment #55
plachAfter this commit I am no longer able to access any Drupal-generated page without Apache crashing in a Windows 8 64-bit + Acquia Dev Desktop (Apache 2.2.22, PHP 5.4.8, MySQL 5.166-community) dev environment. The page is rendered and immediately after Apache dies (you can see the results attached).
I am pretty sure this is the issue causing this behavior: I identified it through git bisect and if I apply -R the committed patch to the latest HEAD everything works fine.
I've no idea of what might be going on, it seems we are triggering some weird PHP bug. Any suggestion?
(Possibly related issue: #2041375: Drupal 8 crashes apache 2.4.4 on 64bit).
Comment #56
dawehnerDoes windows provide some logging of apache, ... is this an actual segfault?
Comment #57
plachNo error in the error.log (obviously :), Windows syslog says:
(translating from italian)
So, yes, I think this is the Windows equivalent of a segfault.
Comment #58
alexpottWe're not alone... http://forumsarchive.laravel.io/viewtopic.php?id=11619
Comment #59
YesCT CreditAttribution: YesCT commented@plach please open an issue with your error and info with the tag
d8 dev environment
(http://drupal.org/project/issues/search?projects=&issue_tags=d8+dev+envi...)
the issue you open might be closed if this is reverted, or if another follow-up issue fixes it, but it is just the kind of d8 dev env thing that me and other people will run into when helping other people get setup with d8 locally. so having an issue will help.
Comment #60
alexpottThere is also https://bugs.php.net/bug.php?id=60369 and https://bugs.php.net/bug.php?id=63002 - plach can you disable wncache or upgrade your php?
Comment #61
plachWinCache is not enabled but upgrading to PHP 5.4.27 does fix the issue :)
@YesCT:
Since it seems we have a fix here, what about just tagging this with "d8 dev environment"?
Comment #62
YesCT CreditAttribution: YesCT commentedwell, did this instead. :)
#2246775: Suggest 5.4.11 as minimum PHP version for Windows and MacOS if XCache is enabled
Comment #63
xjmFWIW, this commit also broke installation for me on OSX 10.8, using PHP 5.4.10 with MAMP (2.1.2). I'm going to try upgrading MAMP and see if it resolves the issue.
Comment #64
martin107 CreditAttribution: martin107 commentedWorks for me
OSX 10.9.2
MAMP 2.2
PHP 5.5.3
Comment #66
YesCT CreditAttribution: YesCT commented