As Drupal is going to use a recent version of Symfony (2.4/2.5/2.6?), it should use the request stack to access the current/master request. Using it allows to remove the need for the request service in the container (and that's a good thing because the request is not a service anyway). This also allows Drupal to get rid of the request scope altogether (a side-effect is a slightly performance improvement.)

CommentFileSizeAuthor
#82 80-82-interdiff.txt947 bytesalexpott
#82 2284103-berdir.82.patch103.44 KBalexpott
#80 2284103-berdir.80.patch102.4 KBalexpott
#78 2284103-berdir.78.patch103.48 KBalexpott
#78 76-78-interdiff.txt1.25 KBalexpott
#76 2284103-berdir.76.patch103.38 KBalexpott
#76 72-76-interdiff.txt3.24 KBalexpott
#72 2284103-berdir.72.patch103.04 KBalexpott
#72 70-72-interdiff.txt1.84 KBalexpott
#70 2284103-berdir.70.patch103.04 KBalexpott
#70 68-70-interdiff.txt2.9 KBalexpott
#68 2284103-berdir.68.patch101.19 KBalexpott
#68 62-68-interdiff.txt8.87 KBalexpott
#63 2284103-berdir.62.patch98.3 KBalexpott
#63 58-62-interdiff.txt3.03 KBalexpott
#61 interdiff-2284103-61.txt629 bytesdamiankloip
#61 2284103-61.patch97.05 KBdamiankloip
#58 2284103-reroll.58.patch96.96 KBBerdir
#53 2284103-reroll.53.patch103.23 KBalexpott
#49 2284103.49.patch114.99 KBalexpott
#49 44-49-interdiff.txt3.18 KBalexpott
#48 drupal_2284103_48.patch117.01 KBXano
#48 interdiff.txt2.21 KBXano
#44 interdiff.txt2.59 KBXen
#44 remove_the_request_from-2284103-44.patch115.26 KBXen
#41 request9.patch120.39 KBfabpot
#39 request9.patch120.38 KBfabpot
#37 2284103.34.patch117.42 KBalexpott
#37 30-34-interdiff.txt23.04 KBalexpott
#30 drupal-without-request-scope.png139.55 KBfabpot
#28 request8.patch97.72 KBfabpot
#26 request7.patch94.69 KBfabpot
#24 request7.patch105.92 KBfabpot
#18 request6.patch79.97 KBfabpot
#16 request5.patch80.82 KBfabpot
#14 request4.patch62.39 KBfabpot
#12 request3.patch62.02 KBfabpot
#9 request2.patch61.69 KBfabpot
#6 request2.patch61.74 KBfabpot
#3 request1.patch2.73 KBfabpot
#1 request1.patch2.46 KBfabpot
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fabpot’s picture

FileSize
2.46 KB
fabpot’s picture

Status: Needs work » Needs review
fabpot’s picture

FileSize
2.73 KB

The last submitted patch, 1: request1.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 3: request1.patch, failed testing.

fabpot’s picture

FileSize
61.74 KB
fabpot’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 6: request2.patch, failed testing.

fabpot’s picture

FileSize
61.69 KB
fabpot’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 9: request2.patch, failed testing.

fabpot’s picture

Status: Needs work » Needs review
FileSize
62.02 KB

Status: Needs review » Needs work

The last submitted patch, 12: request3.patch, failed testing.

fabpot’s picture

Status: Needs work » Needs review
FileSize
62.39 KB

Status: Needs review » Needs work

The last submitted patch, 14: request4.patch, failed testing.

fabpot’s picture

Status: Needs work » Needs review
FileSize
80.82 KB

Status: Needs review » Needs work

The last submitted patch, 16: request5.patch, failed testing.

fabpot’s picture

Status: Needs work » Needs review
FileSize
79.97 KB
Anonymous’s picture

Issue tags: +beta-blocker

adding beta-blocker tag - this sort of change probably can't/shouldn't happen after beta.

also, that will get more eyes on this, even if just to remove the tag ;-)

Anonymous’s picture

Issue tags: -beta-blocker +beta blocker

right tag this time.

Status: Needs review » Needs work

The last submitted patch, 18: request6.patch, failed testing.

Berdir’s picture

Not 100% sure but I think this is very similar to #2223189: Use regular upstream HttpKernel instead of Drupal's custom ?

alexpott’s picture

Priority: Normal » Critical
Issue tags: -beta blocker +beta target
Related issues: +#2223189: Use regular upstream HttpKernel instead of Drupal's custom

I like this issue. I don't think we should have both the request and request_stack services defined - it is both confusing and takes code to maintain. However, this issue should not be beta blocking - it does not meet the criteria. However we should aim to get this done as soon as possible. It is critical as I don't think we should release Drupal 8 without this being fixed.

fabpot’s picture

Status: Needs work » Needs review
FileSize
105.92 KB

Status: Needs review » Needs work

The last submitted patch, 24: request7.patch, failed testing.

fabpot’s picture

Status: Needs work » Needs review
FileSize
94.69 KB

Status: Needs review » Needs work

The last submitted patch, 26: request7.patch, failed testing.

fabpot’s picture

Status: Needs work » Needs review
FileSize
97.72 KB

Status: Needs review » Needs work

The last submitted patch, 28: request8.patch, failed testing.

fabpot’s picture

The last patch fixes almost all tickets. But I'm not able to fix the last ones; I cannot understand what's going on and the code is too complex to understand easily. Anyone willing to help me?

By the way, I've benchmarked the code, and removing the request scope make the default Drupal homepage a bit faster: 2% (not big, but that's a nice side effect.)

perf

larowlan’s picture

This patch breaks the Simpletest UI, fyi.
Was taking a look at the fails and can't get any tests to run via the UI, all failing with

LogicException: Cannot change the ID of an active session in Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy->setId() 

Runs fine via the command-line.
Note that one of the failing tests is SimpleTestTest, so hopefully that means we have coverage for the fact that the UI is broken.

/me keeps digging

Xano’s picture

I have been getting the same error lately for different reasons, but I have not been able to reproduce the problem consistently.

fabpot’s picture

Issue summary: View changes
znerol’s picture

fabpot’s picture

#34

Does it mean that 8.x tests do not pass in a similar way? If that's the case, would it be possible to merge this patch before the root cause is fixed?

znerol’s picture

Re #35 only the UI test runner is affected, the test-bot isn't.

alexpott’s picture

So the good news is that the remaining fails are fixed by other patches.

The patch attached contains all these patches. Also I think we need to do #2272879: Can not run a WebTestBase or KernelTest base tests from inside a simpletest if we're going to do #2272987: Do not persist session manager and #2239969: Session of (UI) test runner leaks into web tests since the last time we committed #2239969: Session of (UI) test runner leaks into web tests we discovered that we were not really testing the UI for the test framework.

Crell’s picture

alexpott: Silly question. If those patches all pass when we merge them together here, how come several are still not RTBC themselves? :-) What's the commit strategy here for this chain?

fabpot’s picture

FileSize
120.38 KB

This new patch removes the management of synchornized service in ContainerBuilder (the code was copy/pasted from Symfony but that's not needed anymore.)

Status: Needs review » Needs work

The last submitted patch, 39: request9.patch, failed testing.

fabpot’s picture

FileSize
120.39 KB

rebase on current 8.x

fabpot’s picture

Status: Needs work » Needs review
fabpot’s picture

Any news on this patch?

Xen’s picture

Patch didn't apply, rebased and fixed two conflicts.

Interdiff might be hosed, interdiff complained.

Status: Needs review » Needs work

The last submitted patch, 44: remove_the_request_from-2284103-44.patch, failed testing.

martin107’s picture

regarding #43 @fabpot I suspect people are not posting patches because it assigned to somebody, perhaps try unassigning

fabpot’s picture

Assigned: fabpot » Unassigned
Xano’s picture

Status: Needs work » Needs review
FileSize
2.21 KB
117.01 KB

I fixed one of the test failures and deleted the test that covered synchronized services, as @fabpot said this is no longer necessary in #39.

alexpott’s picture

FileSize
3.18 KB
114.99 KB

deleted the test that covered synchronized services

Hmmm... but the test shows that we do still need it. If we were not overriding ContainerBuilder::set() to allow us to set services on a frozen container then we would not need it. I looked at trying to remove this override but that would cause this patch to get even bigger.

Also @xano your post was an xpost with mine so interdiff is back to #44.

In order to get this in we need to fix #2272987: Do not persist session manager and #2239969: Session of (UI) test runner leaks into web tests first.

moshe weitzman’s picture

Issue tags: +Performance

dawehner queued 49: 2284103.49.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 49: 2284103.49.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
103.23 KB

Rerolled.

Had some interesting issues with DrupalKernel::getContainer(). This code always calls watchdog until the container can be dumped - but because there is syslog or db_log module enabled this goes no where! In InstallerKernel we currently prevent dumping until the settings.php is written with the hash salt. I've removed this a properly set the allows dumping on DrupalKernel construction by doing:

  // Only allow dumping the container once the hash salt has been created.
  $kernel = InstallerKernel::createFromRequest($request, drupal_classloader(), $environment, (bool) Settings::get('hash_salt', FALSE));

In install.core.inc

We still need #2239969: Session of (UI) test runner leaks into web tests to land. Nearly there.

Status: Needs review » Needs work

The last submitted patch, 53: 2284103-reroll.53.patch, failed testing.

moshe weitzman’s picture

Anyone care to push this Critical along? Would be a pity to lose momentum.

Status: Needs work » Needs review

Berdir queued 53: 2284103-reroll.53.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 53: 2284103-reroll.53.patch, failed testing.

Berdir’s picture

FileSize
96.96 KB

#2239969: Session of (UI) test runner leaks into web tests got in, so here's a re-roll, just a bunch of trivial conflicts due to different comments, empty lines and type safe comparisons.

@moshe: This was blocked on that other issue, there wasn't much to push around here :)

Berdir’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 58: 2284103-reroll.58.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
97.05 KB
629 bytes

These are failing from the call to watchdog() in getContainer() as it is not dumped to disk. The watchdog call is then trying to get the user id() in the LoggerChannel:

    if ($this->currentUser) {
      $context['user'] = $this->currentUser;
      $context['uid'] = $this->currentUser->id();
    }

As the request is only added to the stack in preHandle(), there is no request for AccountProxy > AuthenticationManager to use.

Simplest approach is to not add the id() to the context, and just keep the user. Else, we need to think about either the watchdog call or how the request can be added to the stack. Failure is happening really because the request is not added to the stack.

This should at least isolate and show it passes. Probably not the right solution though.

Status: Needs review » Needs work

The last submitted patch, 61: 2284103-61.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
3.03 KB
98.3 KB

DrupalKernelTest was only passing in HEAD because this code

      if ($this->container) {
        try {
          $instance->setRequest($this->container->get('request'));
          $instance->setCurrentUser($this->container->get('current_user'));
        }
        catch (RuntimeException $e) {
          // We are not in a request context.
        }
      }

In LoggerChannelFactory ... an exception was being through from $this->container->get('request') because we're getting an unset synthetic service... the request stack is not synthetic so this does not occur anymore.

damiankloip’s picture

Looks good!

+++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php
@@ -90,15 +90,15 @@ public function log($level, $message, array $context = array()) {
     if ($this->requestStack && $request = $this->requestStack->getCurrentRequest()) {

Do we need to bother checking for a request stack now? We will always have one?

Ignore me, looks good!

alexpott’s picture

alexpott’s picture

ParisLiakos’s picture

looks great:)

  1. +++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
    @@ -18,14 +19,11 @@
    +  public function __construct(ParameterBagInterface $parameterBag = null)
    +  {
    +      $this->setResourceTracking(false);
    
    +++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
    @@ -99,24 +100,26 @@ public function __construct(RouteProviderInterface $provider, OutboundPathProces
    +  // @todo this should probably be inline in the constructor as this is only
    +  // useful to get some current tests pass
    +  public function updateRequest()
    +  {
    
    +++ b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
    @@ -83,6 +84,8 @@ class AccessManagerTest extends UnitTestCase {
     
    +  protected $requestStack;
    +
    
    +++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
    @@ -133,12 +134,15 @@ function setUp() {
    +    $generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array()), null, $requestStack);
    ...
    +    $generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array('mixed_mode_sessions' => TRUE)), null, $requestStack);
    

    should obey drupal coding standards.
    also some of them miss docs

  2. +++ b/core/lib/Drupal/Core/Form/FormBase.php
    @@ -128,7 +128,7 @@ public function resetConfigFactory() {
       protected function getRequest() {
         if (!$this->request) {
    -      $this->request = $this->container()->get('request');
    +      $this->request = \Drupal::request();
         }
         return $this->request;
    

    shouldnt this method now always use the request stack and not store it somewhere? that way we make sure request doesnt get outdated

  3. +++ b/core/lib/Drupal/Core/Logger/LoggerChannelFactory.php
    @@ -39,16 +39,12 @@ public function get($channel) {
    -        try {
    ...
    -        }
    -        catch (RuntimeException $e) {
    ...
    -        }
    

    thats great:) but lets also remove the use statement from the top of the exception

  4. +++ b/core/modules/book/src/Plugin/Block/BookNavigationBlock.php
    @@ -67,7 +67,7 @@ public static function create(ContainerInterface $container, array $configuratio
    -      $container->get('request'),
    +      $container->get('request_stack')->getCurrentRequest(),
    

    shouldnt we inject the stack instead? that way request wont get outdated

alexpott’s picture

FileSize
8.87 KB
101.19 KB
  1. Fixed - what's wrong with core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php - could see it. The 80 char line length is not mandatory for code.
  2. Using the request stack now
  3. Removed use - that shouldn't have been using the symfony exception anyway.
  4. Using the request stack now

Status: Needs review » Needs work

The last submitted patch, 68: 2284103-berdir.68.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
2.9 KB
103.04 KB

Fixed tests...

ParisLiakos’s picture

thanks

  1. +++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
    @@ -18,14 +19,9 @@
    +  public function __construct(ParameterBagInterface $parameterBag = null) {
    

    needs docblock and null should be uppercase

  2. +++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
    @@ -18,14 +19,9 @@
    +    $this->setResourceTracking(false);
    

    false should be uppercase

  3. +++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
    @@ -125,12 +126,15 @@ function setUp() {
    +    $generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array()), null, $requestStack);
    ...
    +    $generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array('mixed_mode_sessions' => TRUE)), null, $requestStack);
    

    null should be uppercase

alexpott’s picture

FileSize
1.84 KB
103.04 KB

Thanks - couldn't see it :)

ParisLiakos’s picture

Status: Needs review » Reviewed & tested by the community

thanks, this looks really great!

hussainweb’s picture

Not really a review but more of a series of questions about things I didn't really understand. I'd appreciate it if you can clarify on these.

  1. +++ b/core/lib/Drupal.php
    @@ -158,7 +158,7 @@ public static function hasService($id) {
    -    return static::$container && static::$container->has('request') && static::$container->initialized('request') && static::$container->isScopeActive('request');
    +    return static::$container && static::$container->has('request_stack') && static::$container->get('request_stack')->getMasterRequest() !== NULL;
       }
    

    Should we document why we are using getMasterRequest here, compared to getCurrentRequest everywhere else. It might be important.

  2. +++ b/core/lib/Drupal/Core/Session/AccountProxy.php
    @@ -74,7 +74,7 @@ public function setAccount(AccountInterface $account) {
    -      $this->setAccount($this->authenticationManager->authenticate($this->request));
    +      $this->setAccount($this->authenticationManager->authenticate($this->requestStack->getMasterRequest()));
         }
    

    Same here.

  3. +++ b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php
    @@ -116,7 +116,7 @@ function testImageFieldSync() {
    -    $attributes = $this->container->get('request')->attributes;
    +    $attributes = \Drupal::request()->attributes;
    

    Shouldn't we use the container to get the request, rather than using \Drupal? This happens in a few other places as well. I am not too sure about this one but I thought I'd bring it up.

dawehner’s picture

  1. +++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php
    @@ -90,15 +90,15 @@ public function log($level, $message, array $context = array()) {
    +    if ($this->requestStack && $request = $this->requestStack->getCurrentRequest()) {
    ...
    +      if ($this->currentUser) {
    +        $context['user'] = $this->currentUser;
    +        $context['uid'] = $this->currentUser->id();
    +      }
    

    Is there a reason why the current user is now wrapped inside the request stack condition? I could imagine that there might be no request but a manual set user for CLI scripts

  2. +++ b/core/modules/comment/tests/src/Entity/CommentLockTest.php
    @@ -25,8 +27,10 @@ public function testLocks() {
    +    $requestStack = new RequestStack();
    +    $requestStack->push(Request::create('/'));
    +    $container->set('request_stack', $requestStack);
    
    +++ b/core/modules/language/src/LanguageNegotiator.php
    @@ -87,11 +87,12 @@ class LanguageNegotiator implements LanguageNegotiatorInterface {
    +  public function __construct(ConfigurableLanguageManagerInterface $language_manager, PluginManagerInterface $negotiator_manager, ConfigFactoryInterface $config_factory, Settings $settings, RequestStack $requestStack) {
    ...
    +    $this->requestStack = $requestStack;
    
    +++ b/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
    @@ -63,7 +64,9 @@ function setUp() {
    +    $requestStack = new RequestStack();
    +    $requestStack->push($this->request);
    +    $this->container->set('request_stack', $requestStack);
    
    +++ b/core/modules/simpletest/src/TestBase.php
    @@ -1087,7 +1088,10 @@ private function prepareEnvironment() {
    +    $requestStack = new RequestStack();
    +    $requestStack->push($request);
    +    $this->container->set('request_stack', $requestStack);
     
    

    Just in case you have some time please convert that to non-camel-case

  3. +++ b/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
    @@ -63,7 +64,9 @@ function setUp() {
         $this->request = Request::createFromGlobals();
    -    $this->container->set('request', $this->request);
    ...
     
    

    This example actually should just push a new request onto the container? It already will have a stack.

alexpott’s picture

FileSize
3.24 KB
103.38 KB

@hussainweb #74

  1. This is checking if we have a request it is used is super early code... if we have a master request then we have a request.
  2. Authentication should be done against the master request
  3. This is a test - does not matter

@dawehner #75

  1. The current_user depends on the request_stack if we want to decouple this then we have to decouple that - not for this issue.
  2. Sure
  3. Yeah that looks weird let's try this
catch’s picture

Status: Reviewed & tested by the community » Needs work

I think we should add inline docs for #74/#76 #1, needs an explanation there to make it clear what's going on. Didn't spot anything else obvious.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
1.25 KB
103.48 KB

Actually I don't think Drupal::hasRequest() has any real reason to use getMasterRequest so lets change that so it maps nicely to Drupal::request().

Added a comment for the authentication use case.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 78: 2284103-berdir.78.patch, failed testing.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
102.4 KB

Needed a reroll due to #2196241: Remove string translation services from TestBase container a whole hunk of request and container futzing in TestBase was ripped out. Nice!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 80: 2284103-berdir.80.patch, failed testing.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
103.44 KB
947 bytes

Need to use request_stack (not request) in the install tests.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.x, thanks!

  • catch committed 02a32e3 on 8.x
    Issue #2284103 by alexpott, fabpot, damiankloip, Xano, Xen, Berdir:...
sun’s picture

Question:

I've studied this change intensively, but I'm not able to see where & how the request_stack gets re-injected into the rebuilt container after a call to DrupalKernel::updateModules().

It magically appears to exist, and the current Request object is the identical object as the one prior to calling updateModules(), but somehow I fail to see the responsible lines of code for that (since this patch seemingly removed the code that manually re-injected it).

Can someone enlighten me? (Or am I looking at a mystery?)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.