Problem/Motivation

This is not really a competitive patch but some of the slow down that's been central to this problem has to do with (I think) when the typed data manager stuff gets called. Looking at this further, I was troubled by the implications of the public setters on the classes, so I attempted to remove them and rework Context classes as dumb data objects. The tagged context services that are ALSO event subscribers are just weird to me. I see what we're attempting to do with the @service_id, but it still seems odd to me. Just want to make sure we don't have other options. I don't expect this will pass, I have no clue about the performance.

From #2354889-65: Make block context faster by removing onBlock event and replace it with loading from a ContextManager

Proposed resolution

Context objects become immutable.

Remove ContextInterface::setContextValue() and ContextInterface::setContextDefinition()
Add $context_value = NULL as the second parameter to Context::__construct()
Add \Drupal\Core\Plugin\Context\ContextInterface::createFromContext(ContextInterface $old_context, $value) for modifying an existing context

Old code

function whatever(ContextInterface $some_context) {
  $context->setContextValue('some new value');
  return $context;
}

New code

function whatever(ContextInterface $some_context) {
  $context = Context::createFromContext($context, 'some new value');
  return $context;
}

Remaining tasks

N/A

User interface changes

N/A

API changes

See "Proposed changes"

Data model changes

N/A

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug because:
Usage of the plugin context API has not been widespread in core, but as implementation in contrib has begun to occur, it's become clear that the mutability of context objects could cause all sorts of problems since any plugin could radically alter context injected into it for the entire system.
Issue priority Major because:
This does not break core without contrib doing something bad, however the setter methods that enable this should not be supported by core. We must remove them.
Prioritized changes The main goal of this issue is performance. This issue was initially filed to prevent unnecessary calls to Typed Data during context creation which can be quite costly.
CommentFileSizeAuthor
#92 2508884-immutable-context-92.patch29 KBtim.plunkett
#92 interdiff.txt2 KBtim.plunkett
#87 2508884-immutable-context-87.patch29.46 KBtim.plunkett
#87 interdiff.txt2.93 KBtim.plunkett
#80 interdiff.txt2.71 KBtim.plunkett
#80 2508884-immutable-context-80.patch29.6 KBtim.plunkett
#79 interdiff.txt2.21 KBtim.plunkett
#79 2508884-immutable-context-79.patch29.66 KBtim.plunkett
#73 interdiff.txt3.04 KBtim.plunkett
#73 2508884-immutable-context-73.patch27.46 KBtim.plunkett
#69 2508884-immutable-context-69.patch25.55 KBtim.plunkett
#69 interdiff.txt6.92 KBtim.plunkett
#66 interdiff.txt20.96 KBdsnopek
#66 drupal8-context-immutable-2508884-66.patch25.6 KBdsnopek
#61 interdiff.txt10.4 KBdsnopek
#61 drupal8-context-immutable-2508884-61.patch35.29 KBdsnopek
#56 drupal8-context-immutable-2508884-55.patch38.11 KBdsnopek
#53 interdiff.txt1.46 KBdsnopek
#53 drupal8-context-immutable-2508884-53.patch38.11 KBdsnopek
#45 2508884-21-45-interdiff.txt22.52 KBjaperry
#45 2508884-45.patch39.48 KBjaperry
#39 interdiff-2508884-33.txt6.64 KBdsnopek
#39 interdiff-2508884-31.txt8.57 KBdsnopek
#33 make_block_contexts-2508884-32.patch34.62 KBsravya_12
#31 2508884-22.patch39.05 KBswathin
#21 2508884-interdiff.txt4.32 KBeclipsegc
#21 2508884-21.patch38.33 KBeclipsegc
#19 2508884-19.patch34.75 KBeclipsegc
#17 2508884-17.patch35.33 KBeclipsegc
#17 2508884-interdiff.txt6.41 KBeclipsegc
#15 2508884-14.patch31.68 KBeclipsegc
#8 2508884-interdiff-5-8.txt3 KBeclipsegc
#8 2508884-interdiff-3-5.txt6.07 KBeclipsegc
#8 2508884-8.patch31.4 KBeclipsegc
#5 2508884-5.patch32.91 KBeclipsegc
#3 2508884-3.patch26.84 KBeclipsegc

Comments

wim leers’s picture

Issue tags: +Performance
wim leers’s picture

Title: Make block contexts faster by using less type data » Make (block) contexts faster by using less TypedData
eclipsegc’s picture

Status: Active » Needs review
StatusFileSize
new26.84 KB

To a certain degree I feel like we're using MORE TypedData here, we're just not asking Drupal to do the work, but instead expecting the developer to do it. The main objective here was to prevent calls to the TypedDataManager during set*() methods and during __construct(). This resulted in the removal of all set*() methods on the ContextInterface. TypedData objects themselves have a setValue() method, so to a certain degree this improvement is moot because of that, but at least we've removed another layer of the problem space and placed the greater problem squarely with TypedData. TypedDataInterface itself might benefit from a similar refactor, but that's a separate issue.

This patch needs a bit of love yet since I added TypedDataInterface dependencies into Plugin Components, but I want to see how this fairs with tests.

Eclipse

Status: Needs review » Needs work

The last submitted patch, 3: 2508884-3.patch, failed testing.

eclipsegc’s picture

Status: Needs work » Needs review
StatusFileSize
new32.91 KB

Cleaning up the tests, some of these have very strange errors in testbot. The component/core issue I mentioned earlier apparently has a test (cool!) I've not tried to fix that yet, will do that once the rest of it appears to be passing.

Eclipse

wim leers’s picture

Interdiff?

Status: Needs review » Needs work

The last submitted patch, 5: 2508884-5.patch, failed testing.

eclipsegc’s picture

Status: Needs work » Needs review
StatusFileSize
new31.4 KB
new6.07 KB
new3 KB

Sorry Wim, my bad. I've added interdiffs from 3-5 and 5-8 now. I EXPECT this patch to pass. If it does, I'd love to see if this makes a performance difference.

Eclipse

wim leers’s picture

Issue tags: +API change, +needs profiling

Nice, green! :)

dsnopek’s picture

Issue tags: +D8panels
wim leers’s picture

Priority: Normal » Major

Probably major given the performance impact. But we don't have numbers yet, so definitely not critical.

fabianx’s picture

Could we get an IS update, please?

dawehner’s picture

@ecliseGC
In case you really want a profiling keep the patch up to date, please.

fabianx’s picture

Issue tags: +Needs reroll
eclipsegc’s picture

StatusFileSize
new31.68 KB

Reroll

Some of the conflicts break the immutability of context, but we can fix that after we see how test bot feels.

Eclipse

Status: Needs review » Needs work

The last submitted patch, 15: 2508884-14.patch, failed testing.

eclipsegc’s picture

Status: Needs work » Needs review
StatusFileSize
new6.41 KB
new35.33 KB

Fixing an error in the reroll and attempting to make sure that this takes advantage of cacheable metadata.

Eclipse

Status: Needs review » Needs work

The last submitted patch, 17: 2508884-17.patch, failed testing.

eclipsegc’s picture

Status: Needs work » Needs review
StatusFileSize
new34.75 KB

Thank you berdir for pointing out that I deleted NodeRouteContext.

Eclipse

Status: Needs review » Needs work

The last submitted patch, 19: 2508884-19.patch, failed testing.

eclipsegc’s picture

Status: Needs work » Needs review
StatusFileSize
new38.33 KB
new4.32 KB

Attempting to fix the core ContextTest and maintain the immutability of the Context object.

Eclipse

wim leers’s picture

Issue tags: -Needs reroll

No more need for a reroll, but now that we have a green patch: very much needs profiling.

fabianx’s picture

And an IS update of _what_ this does and why and what the impact on core / contrib is.

dawehner’s picture

Here it is

### FINAL REPORT

=== 8.0.x..8.0.x compared (559a51d20291e..559a522bf0bb6):

ct  : 27,498|27,498|0|0.0%
wt  : 87,758|87,742|-16|-0.0%
mu  : 14,875,872|14,875,872|0|0.0%
pmu : 14,942,784|14,942,784|0|0.0%

=== 8.0.x..2508884 compared (559a51d20291e..559a5244893bc):

ct  : 27,498|27,318|-180|-0.7%
wt  : 87,758|86,786|-972|-1.1%
mu  : 14,875,872|14,506,960|-368,912|-2.5%
pmu : 14,942,784|14,571,920|-370,864|-2.5%

---
ct = function calls, wt = wall time, cpu = cpu time used, mu = memory usage, pmu = peak memory usage

### XHPROF-LIB REPORT

+-------------------+------------+------------+------------+------------+------------+
| namespace         |        min |        max |       mean |     median |       95th |
+-------------------+------------+------------+------------+------------+------------+
| Calls             |            |            |            |            |            |
|                   |            |            |            |            |            |
| 2508884           |     27,318 |     29,005 |     27,335 |     27,318 |     27,318 |
| 8_0_x             |     27,498 |     29,328 |     27,516 |     27,498 |     27,498 |
|                   |            |            |            |            |            |
| Wall time         |            |            |            |            |            |
|                   |            |            |            |            |            |
| 2508884           |     86,786 |    106,730 |     92,074 |     91,418 |     98,903 |
| 8_0_x             |     87,742 |    110,710 |     93,008 |     92,020 |    101,632 |
|                   |            |            |            |            |            |
| Memory usage      |            |            |            |            |            |
|                   |            |            |            |            |            |
| 2508884           | 14,506,936 | 14,958,464 | 14,541,022 | 14,506,960 | 14,688,080 |
| 8_0_x             | 14,875,712 | 15,326,856 | 14,908,704 | 14,875,872 | 15,279,224 |
|                   |            |            |            |            |            |
| Peak memory usage |            |            |            |            |            |
|                   |            |            |            |            |            |
| 2508884           | 14,571,824 | 15,087,328 | 14,606,553 | 14,571,920 | 14,751,632 |
| 8_0_x             | 14,942,472 | 15,456,400 | 14,976,315 | 14,942,784 | 15,344,040 |
|                   |            |            |            |            |            |
+-------------------+------------+------------+------------+------------+------------+
wim leers’s picture

jibran’s picture

Issue tags: -needs profiling

After profiling is it a critical or not?

fabianx’s picture

Not critical at all.

yched’s picture

Got pointed here by @dsnopek after my comment in #2375695-141: Condition plugins should provide cache contexts AND cacheability metadata needs to be exposed

Copy pasting from over there :

The cacheability metadata that got added to Context seems to depend on the history of values the context received over time. - e.g changing a context value from node 1 to node 2 causes the context to have both cache tags node:1 and node:2. while a fresh context created directly with node 2 will only have node:2.

This feels like the kind of histeresis we usually try to avoid ? I guess changing a Context value is not a very common situation, but then again the setContextValue() method is public, so we can't pretend contexts are immutable ?

So it seems that is another good reason to push through with the approach here of making contexts actually immutable :-)

(Sorry for the noise if that was a concerted plan from the get go. The two issues didn't seem to explicitly relate to each other, nor did #2375695: Condition plugins should provide cache contexts AND cacheability metadata needs to be exposed mentioned the question of immutability, so at least this is an attempt to make it explicit somewhere)

wim leers’s picture

yched++

fabianx’s picture

Title: Make (block) contexts faster by using less TypedData » Make (block) contexts faster by using less TypedData and make contexts immutable
Category: Task » Bug report

Yes, +1 to immutable context objects.

Re-classifying as a bug.

What I am unclear is:

- What API changes does this make?
- What is the impact on already existing contrib modules?

swathin’s picture

StatusFileSize
new39.05 KB

Worked on this issue and here is the new patch.

Status: Needs review » Needs work

The last submitted patch, 31: 2508884-22.patch, failed testing.

sravya_12’s picture

Status: Needs work » Needs review
Issue tags: -Performance, -API change, -D8panels, -Needs issue summary update, -Needs reroll +#DHCSprint
StatusFileSize
new34.62 KB

Rerolled from comment #19

Status: Needs review » Needs work

The last submitted patch, 33: make_block_contexts-2508884-32.patch, failed testing.

eclipsegc’s picture

@swathin, @sravya

You need to provide interdiffs with your patches so that people can keep up with your work without having to reread the whole patch.

@Fabianx

The thing it primarily affects is the context providers. Core (as you well know) does a little of this, and Page_manager and Rules. Neither Page_manager nor Rules are far enough along that this would be a huge issue for this. I tend to think (as someone helping develop on of the modules most heavily impacted by this) that it's unlikely to cause huge issue.

Eclipse

fabianx’s picture

#35: It would be great if you could update the issue summary and add a beta evaluation.

I have already pasted the template in.

---

I know it is a lot of effort to take care of issue summaries and beta evaluations, but it really helps others understand the issues and such they can be both more effective in review and helping. Also usually those issues get to be committed much faster.

eclipsegc’s picture

Issue summary: View changes

filling in beta evaluation template.

eclipsegc’s picture

Issue summary: View changes
dsnopek’s picture

StatusFileSize
new8.57 KB
new6.64 KB

Restoring some of the issue tags that were lost in #33. Also, I attempted to make some interdiffs (attached) for the patches in #31 and #33, but no promises that they're correct. :-)

dsnopek’s picture

Issue tags: +Needs reroll

And needs a reroll!

dsnopek’s picture

Issue tags: +Performance, +API change, +D8panels

Er, 2nd attempt at adding the tags back. :-/

dsnopek’s picture

Issue tags: -Needs reroll

Er, nevermind, doesn't need a reroll! I was on the wrong branch left over from generating the interdiffs. Sorry for all the comments so quickly!

wim leers’s picture

Issue tags: -Needs beta evaluation

Beta evaluation was added, IS still needs an update AFAICT.

japerry’s picture

There is a left-over TODO -- but its very close!

japerry’s picture

Status: Needs work » Needs review
StatusFileSize
new39.48 KB
new22.52 KB

Okay first shot re-roll of 21.

Status: Needs review » Needs work

The last submitted patch, 45: 2508884-45.patch, failed testing.

The last submitted patch, 45: 2508884-45.patch, failed testing.

japerry’s picture

Waiting for @timplunkett to give his snarky review. ;)

tim.plunkett’s picture

My snarky review from yesterday got eaten because I took too long to post. Here are the important parts, sans snark.

  1. +++ b/core/lib/Drupal/Core/Language/ContextProvider/CurrentLanguageContext.php
    @@ -57,8 +59,9 @@ public function getRuntimeContexts(array $unqualified_context_ids) {
    -        $context = new Context(new ContextDefinition('language', $info[$type_key]['name']));
    -        $context->setContextValue($this->languageManager->getCurrentLanguage($type_key));
    +        $context_value = Language::createInstance(DataDefinition::createFromDataType('language'));
    +        $context_value->setValue($this->languageManager->getCurrentLanguage($type_key));
    +        $context = new Context(new ContextDefinition('language', $info[$type_key]['name']), $context_value);
    

    This kinda sucks as an API change. Why force us to think about TypedData more than we have to?

  2. +++ b/core/modules/node/src/ContextProvider/NodeRouteContext.php
    @@ -44,12 +45,12 @@ public function getRuntimeContexts(array $unqualified_context_ids) {
    -      $context->setContextValue(Node::create(array('type' => $node_type->id())));
    +      $context = new Context(new ContextDefinition('entity:node'), EntityAdapter::createFromEntity(Node::create(array('type' => $node_type->id()))));
    

    new new create create a b start

    That's a LOT of things to know. From an Entity to TypedData to ContextDefinition to Context? Why should I have to know that much?

  3. +++ b/core/modules/user/src/Tests/Condition/UserRoleConditionTest.php
    @@ -133,7 +134,7 @@ public function testConditions() {
    -    $condition->setContextValue('user', $this->authenticated);
    +    $condition->setContextValue('user', EntityAdapter::createFromEntity($this->authenticated));
    

    This sort of change isn't as bad, but it's still extra work

tim.plunkett’s picture

If NodeRouteContext had its code rearranged slightly, the change I called out in #49.2 would be this:

-      $context->setContextValue($node);
+      $context = new Context(new ContextDefinition('entity:node'), EntityAdapter::createFromEntity($node));

That's pretty awful.

+++ b/core/modules/node/src/ContextProvider/NodeRouteContext.php
@@ -44,12 +45,12 @@ public function getRuntimeContexts(array $unqualified_context_ids) {
     $context = new Context(new ContextDefinition('entity:node', NULL, FALSE));

Also this should probably be $context = NULL; and then after the other calls: if (!$context) { this line.

dsnopek’s picture

new new create create a b start

Does that code give you 30 lives in Super IssueQueuetra (tm)?

dsnopek’s picture

Assigned: Unassigned » dsnopek
-      $context->setContextValue($node);
+      $context = new Context(new ContextDefinition('entity:node'), EntityAdapter::createFromEntity($node));

That's pretty awful.

In a functional programming language (or using functional programming style in any language) that would be totally normal! But point taken in Drupal-land.

Would a helper function be enough? For example, something like:

$context->cloneWithValue($node);

I dunno if anyone is still working on this, but I may take a stab at fixing the tests after I finish catching up on issues...

dsnopek’s picture

Status: Needs work » Needs review
StatusFileSize
new38.11 KB
new1.46 KB

So... I like the immutability of the Context object in this patch.

But assuming I'm understanding this, the performance improvement is from not calling TypedDataManager::create() and requiring the developer to convert the context values to typed data themselves. I'm not terribly crazy about that at all. :-/

I totally misunderstood what @tim.plunkett was complaining about above in #49 and #50. I thought it was about have to initialize so many objects, but it's about the extra knowledge that the developer has to have.

The performance improvement would be nice, but not at this high of a DX cost. Maybe we could split this into two issues: (1) for the immutability of the Context objects, and (2) for removing calls to TypedDataManager::create()?

Anyway, here's a new patch that may or may not pass more tests...

dsnopek’s picture

Assigned: dsnopek » Unassigned

Status: Needs review » Needs work

The last submitted patch, 53: drupal8-context-immutable-2508884-53.patch, failed testing.

dsnopek’s picture

Status: Needs work » Needs review
StatusFileSize
new38.11 KB

This is what I really meant. :-)

The last submitted patch, 53: drupal8-context-immutable-2508884-53.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 56: drupal8-context-immutable-2508884-55.patch, failed testing.

The last submitted patch, 56: drupal8-context-immutable-2508884-55.patch, failed testing.

tim.plunkett’s picture

Title: Make (block) contexts faster by using less TypedData and make contexts immutable » Make contexts immutable

Talked with @japerry and @EclipseGc and agreed we'll just work on the immutability, and remove the TypedData changes.

dsnopek’s picture

StatusFileSize
new35.29 KB
new10.4 KB

Cool! Then I have a half finished patch which adds a $context->cloneWithValue($value) and even a few conversions (or revert-sions?). It still needs lots of work (most of the typed data changes are still there), but it's a start.

dsnopek’s picture

Status: Needs work » Needs review

Just curious what textbook will say

Status: Needs review » Needs work

The last submitted patch, 61: drupal8-context-immutable-2508884-61.patch, failed testing.

The last submitted patch, 61: drupal8-context-immutable-2508884-61.patch, failed testing.

dsnopek’s picture

Assigned: Unassigned » dsnopek

Working on this now...

dsnopek’s picture

Status: Needs work » Needs review
StatusFileSize
new25.6 KB
new20.96 KB

Ok! This should just be changes to make the context immutable. Let's see what the testbot thinks!

tim.plunkett’s picture

+++ b/core/modules/node/src/ContextProvider/NodeRouteContext.php
@@ -44,12 +44,12 @@ public function getRuntimeContexts(array $unqualified_context_ids) {
-        $context->setContextValue($node);
+        $context = $context->cloneWithValue($node);

I need to think about this naming, because it doesn't feel right, but I don't yet have a better name.

Otherwise, this is looking great! Thanks @dsnopek

dsnopek’s picture

Assigned: dsnopek » Unassigned

Cool, thanks! Unassigning for now...

tim.plunkett’s picture

StatusFileSize
new6.92 KB
new25.55 KB

Okay, a long talk with @japerry, @EclipseGc, and @dsnopek, this is what we came up with.

\Drupal\Core\Plugin\Context\ContextInterface will have this:

  public static function createFromContext(ContextInterface $old_context, $value);

\Drupal\Component\Plugin\Context\ContextInterface does not need a dedicated method, since it is not concerned with preserving cacheability. It can just use the constructor directly.

dsnopek’s picture

I think this patch looks great! Assuming tests pass, this is RTBC as far as I'm concerned. :-) Unfortunately, since I wrote a bunch of this code, I can't RTBC it.

Status: Needs review » Needs work

The last submitted patch, 69: 2508884-immutable-context-69.patch, failed testing.

The last submitted patch, 69: 2508884-immutable-context-69.patch, failed testing.

tim.plunkett’s picture

StatusFileSize
new27.46 KB
new3.04 KB

As pointed out by @dsnopek, \Drupal\Component\Plugin\ContextAwarePluginBase::__construct() hardcoded the Component Context class. This allows us to override it.

tim.plunkett’s picture

Status: Needs work » Needs review
dsnopek’s picture

Interdiff looks good! Hopefully this one'll pass tests. :-)

Status: Needs review » Needs work

The last submitted patch, 73: 2508884-immutable-context-73.patch, failed testing.

The last submitted patch, 73: 2508884-immutable-context-73.patch, failed testing.

eclipsegc’s picture

+++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php
@@ -41,19 +41,33 @@
+
+    if (isset($configuration['context'])) {
+      $this->contexts = $this->extractContextFromConfiguration($configuration);
+      unset($this->configuration['context']);

This should happen before the parent::__construct() call. The removal of context from configuration is to keep config at the parent level from having to deal with this at all ever.

Otherwise this seems fine.

Eclipse

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new29.66 KB
new2.21 KB

Skipping #78 for the moment, just want to see the failure numbers.

tim.plunkett’s picture

StatusFileSize
new29.6 KB
new2.71 KB

Here is my closest approximation of what I think @EclipseGc wants.

We cannot simply move the __construct later, since we call getContextDefinition, which needs $this->getPluginDefinition().

The last submitted patch, 73: 2508884-immutable-context-73.patch, failed testing.

eclipsegc’s picture

+10000000

Looks great from my end, who can rtbc this?

Eclipse

cosmicdreams’s picture

Status: Needs review » Reviewed & tested by the community

I can. In reading this I think I get what your shooting for.

andypost’s picture

IS still needs update!

tim.plunkett’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

Done

wim leers’s picture

  1. +++ b/core/lib/Drupal/Component/Plugin/Context/Context.php
    @@ -31,20 +31,16 @@ class Context implements ContextInterface {
    +   * @param mixed $context_value|NULL
    
    +++ b/core/lib/Drupal/Core/Plugin/Context/Context.php
    @@ -43,11 +43,19 @@ class Context extends ComponentContext implements ContextInterface {
    +   * @param mixed $context_value|NULL
    

    Nit: mixed|null $context_value

  2. +++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php
    @@ -41,17 +41,30 @@
    +   * Converts any context mappings from configuration into context objects.
    ...
    +  protected function createContextFromConfiguration(array $context_configuration) {
    

    Nit: "Converts" in the doc, vs "create" in the method name. Let's be consistent.

  3. +++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php
    @@ -41,17 +41,30 @@
    +   *   An array of context objects.
    

    Nit: "[…], keyed by …." — but this also doesn't happen elsewhere, so probably we don't want this either?

  4. +++ b/core/lib/Drupal/Core/Plugin/Context/Context.php
    @@ -170,4 +174,14 @@ public function getCacheMaxAge() {
    +    $context = new static($old_context->getContextDefinition(), $value);
    +    $context->addCacheableDependency($old_context);
    +    $context->setTypedDataManager($old_context->getTypedDataManager());
    +    return $context;
    

    Nit: In principle this could all be chained.

  5. +++ b/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php
    @@ -17,6 +17,14 @@
    +   *   The defining characteristic representation of the context.
    

    What is a "defining characteristic representation"?

  6. +++ b/core/modules/system/tests/modules/condition_test/src/Tests/OptionalContextConditionTest.php
    @@ -58,6 +59,8 @@ protected function testContextNoValue() {
    +    $type = NodeType::create(['type' => 'example', 'name' => 'Example']);
    +    $type->save();
    

    Nit: NodeType::create([…])->save()

tim.plunkett’s picture

StatusFileSize
new2.93 KB
new29.46 KB

1) Yep
2) Sure
3) Leaving as is.
4) Yes, but leaving as is
5) That's c/p from the parent, using inheritdoc instead (we're only defining this to override the @return docblock)
6) Sure.

wim leers’s picture

RTBC++

+++ b/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php
@@ -17,10 +17,9 @@
   /**
-   * Gets the provided definition that the context must conform to.
+   * {@inheritdoc}
    *
    * @return \Drupal\Core\Plugin\Context\ContextDefinitionInterface
-   *   The defining characteristic representation of the context.
    */
   public function getContextDefinition();

Yay for not spreading a crazy doc :P

But why keep the @return?

tim.plunkett’s picture

Because of the crazy split between
\Drupal\Component\Plugin\Context\ContextInterface
and
\Drupal\Core\Plugin\Context\ContextInterface

It helps immensely to typehint correctly between Component and Core.

wim leers’s picture

Okay, thanks for the explanation!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record
  1. I think given that context is passed around through layers of the application making it immutable is very sensible and will be prevent a whole class of bugs in the D8 life cycle. I'm +1 for this change as reducing fragility and unblocking contrib.
  2. This is an API change and therefore needs a CR
  3. +++ b/core/lib/Drupal/Core/Plugin/Context/Context.php
    @@ -170,4 +174,14 @@ public function getCacheMaxAge() {
    +    $context->setTypedDataManager($old_context->getTypedDataManager());
    

    The getTypedDataManager method is not on the interface. Is that ok?

  4. +++ b/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php
    @@ -24,16 +31,6 @@
    -  public function setContextData(TypedDataInterface $data);
    

    Can remove the use TypedDataInterface...

  5. +++ b/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php
    @@ -15,6 +15,7 @@
    +use Drupal\Core\TypedData\TypedDataInterface;
    

    Not used.

  6. +++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php
    @@ -8,9 +8,12 @@
    +use Drupal\Core\Plugin\Context\Context;
    

    Not used.

tim.plunkett’s picture

Status: Needs work » Needs review
Issue tags: -Needs change record
StatusFileSize
new2 KB
new29 KB

2) Added #2575711: Context objects are now immutable
3) It's not on any interface, so we have no way to check that. But that is a pre-existing condition in HEAD. As such, I'm including a method_exists call here, but not adding any interfaces.
4) No, it's used elsewhere in the file
5) Yep
6) Yep

Status: Needs review » Needs work

The last submitted patch, 92: 2508884-immutable-context-92.patch, failed testing.

Status: Needs work » Needs review
japerry’s picture

Status: Needs review » Reviewed & tested by the community

The patch in #92 appears to fix the concerns in #91, thus marking RTBC to get back into Alex's visibility.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

I'm committing this API change under the core committer discretion clause of the beta policy since I think it will eliminate a whole class of likely problem in contrib. Committed 91b4ae5 and pushed to 8.0.x. Thanks!

diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php b/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php
index 967819a..067e76a 100644
--- a/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextInterface.php
@@ -9,7 +9,6 @@
 
 use Drupal\Component\Plugin\Context\ContextInterface as ComponentContextInterface;
 use Drupal\Core\Cache\CacheableDependencyInterface;
-use Drupal\Core\TypedData\TypedDataInterface;
 
 /**
  * Interface for context.

Removing the unused use from #91.4 on commit.

  • alexpott committed 91b4ae5 on 8.0.x
    Issue #2508884 by EclipseGc, tim.plunkett, dsnopek, japerry, sravya_12,...
Torenware’s picture

It would appear this commit broke Rules 8.x-3.x pretty hard. I'm not up enough on this issue to know the details of this issue, but I suspect fago et al may need to be involved here.

eclipsegc’s picture

That's not surprising, it broke page_manager too, but they just need to stop using the setters and start using the constructor. Should be a pretty straight forward fix.

Eclipse

dsnopek’s picture

@Torenware: The change record describes how code needs to be updated https://www.drupal.org/node/2575711

Torenware’s picture

@dsnopek,

Thanks. I've looked at that now and spent a day applying that to the Rules code base.

One thing I've having trouble with: Rules has a concept of a set context that has a value of NULL. Post this patch, this is busted, and I don't see a valid way to have a set context with a NULL value. Setting it NULL directly won't work, and I don't see a way to create a TypedData object that gets around the problem either.

Is there some way of doing this I'm not seeing, or does the fix for this issue disallow a context with a NULL value?

klausi’s picture

Status: Fixed » Closed (fixed)

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