Problem/Motivation

NodeController::revisionOverview() loads every revision. If you have a lot of edits for one node, then that leads to max_execution_time being exceeded (or potentially memory limit depending on what gets hit first).

Proposed resolution

Add a pager.

Remaining tasks

Add a pager.

User interface changes

There'll be a pager if there are lots of revisions, instead of a fatal error.

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

catch created an issue. See original summary.

catch’s picture

Title: NodeController:revisionOverview() does not have a pager » NodeController::revisionOverview() does not have a pager
kamalrajsahu21’s picture

Here is the patch adding limit and offset on revisionIds function of NodeStorage class

mohit_aghera’s picture

Status: Active » Needs review

Changing to Needs review so test bot can trigger testing.

dawehner’s picture

a) We change the public interface, this should not happen
b) We construct a SQL query using strings, let's switch to db_select() instead
c) IMHO we should just skip using this method and go to use an entity query in the first place.

rfay’s picture

Status: Needs review » Needs work

In addition to @dawehner's review issues in #5, the patch provided does not implement a pager for the revisions UI (NodeController::revisionOverview()), so doesn't get us close enough to the needed solution. But it's a start!

If I understand (c) in #5, @dawehner is saying "just dump this method and use an entity query directly in NodeController::revisionOverview()", which would work fine IMO.

dawehner’s picture

If I understand (c) in #5, @dawehner is saying "just dump this method and use an entity query directly in NodeController::revisionOverview()", which would work fine IMO.

Yeah exactly. https://github.com/fago/entity/blob/8.x-1.x/src/Controller/RevisionContr... has an example of that already.

mohit_aghera’s picture

Status: Needs work » Needs review
FileSize
1.75 KB

@dawehner
I have changed query for initial testing, does this sounds good ?
Updated code from fresh 8.2.x so no interdiff added.

Status: Needs review » Needs work

The last submitted patch, 8: drupal-add-pager-for-revision-2746033-8.patch, failed testing.

amateescu’s picture

Version: 8.2.x-dev » 8.1.x-dev
Status: Needs work » Needs review
Issue tags: +Workflow Initiative, +DevDaysMilan
FileSize
1.14 KB
2.45 KB

@dawehner was correct in #5.c), we cannot change \Drupal\node\NodeStorage::revisionIds() in any way because that would be an API change, as proven by the test fails in #8, so let's skip using the node storage method and just write our own entity query.

Do we want to test the new pager behavior for revisions overview page?

Also, no API change means that this could go into 8.1.x as well?

dawehner’s picture

Issue tags: +Needs tests

Yeah let's add a test for it. Beside this is looking fine. Maybe for readability reasons this could be moved to a protected method.

amateescu’s picture

Ok then, here's a test. Not attaching a test-only patch because it's testing new behavior introduced by this issue.

Oops, forgot about moving the query to a protected method. Attaching a second interdiff for that :)

dawehner’s picture

+++ b/core/modules/node/src/Tests/NodeRevisionsAllTest.php
@@ -64,6 +56,33 @@ protected function setUp() {
+    $node->setNewRevision();
+    $node->save();
+
+    $node_storage->resetCache(array($node->id()));
+
+    // Make sure we get revision information.
+    return $node_storage->load($node->id());

Wait, this resetCache call is really needed? This sounds like a bug, don't you think so? Seems so out of scope of this issue to discuss about that. If needed thought loadUnchanged() does the same kind of stuff.

amateescu’s picture

Turns out most of that is not needed at all.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Nice

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 14: 2746033-14.patch, failed testing.

amateescu’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: +Triaged core major

Discussed with @alexpott, @catch, @xjm, @dixon, @berdir, @effulgentsia, @timmillwood - we decided to keep it as major. Also setting back to RTBC after a random DrupalCI error.

xjm’s picture

Title: NodeController::revisionOverview() does not have a pager » NodeController::revisionOverview() does not have a pager, which results in unlimited queries
xjm’s picture

Version: 8.1.x-dev » 8.2.x-dev
Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/node/src/Controller/NodeController.php
    @@ -170,12 +171,9 @@ public function revisionOverview(NodeInterface $node) {
    -    foreach (array_reverse($vids) as $vid) {
    +    foreach ($this->getRevisionIds($node, $node_storage) as $vid) {
    

    At first I was unsure why the array_reverse() was going away here, but now I see. NodeStorage::revisionIds() loads the full list, ascending. The new method in the patch selects them in descending order. Edit: Point being, this is correct.

  2. +++ b/core/modules/node/src/Controller/NodeController.php
    @@ -279,4 +279,25 @@ public function addPageTitle(NodeTypeInterface $node_type) {
    +  protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
    

    This adds a protected method to a controller, which is a safe internal API change. Since this is a major-at-least bug, we also should backport the fix to 8.1.x. In that case would we add an underscore to the beginning of its name? That's the strategy we've used before and is documented on our API policy: https://www.drupal.org/core/d8-bc-policy#underscore

  3. +++ b/core/modules/node/src/Controller/NodeController.php
    @@ -279,4 +279,25 @@ public function addPageTitle(NodeTypeInterface $node_type) {
    +      ->pager(50)
    

    I questioned whether this should be hardcoded, but I see it is already hardcoded this way for users and comments, so this seems acceptable for a major (and increasingly critical) bug fix.

Unfortunately, the patch does not seem to apply to 8.2.x. Can we reroll it for that branch, then look at the backport? (It's most critical in 8.2.x where all nodes are already revisioned by default, although the bug will still also cause fatals on 8.1.x sites where revisioning is enabled for large content types.)

mohit_aghera’s picture

Status: Needs work » Needs review
FileSize
5.22 KB

Re-roll for Drupal 8.2.x
Fixed one more issue and changed order to Ascending.

Status: Needs review » Needs work

The last submitted patch, 20: 2746033-20.patch, failed testing.

xjm’s picture

@mohit_aghera, thanks for the reroll.

I did not mean that the order should be ascending. Descending is correct. array_reverse() of ascending is descending. :) I will edit my comment to make that clearer; I was just documenting questions I had while reviewing and what the answers were.

Also, be sure to provide an interdiff when you update patches. In this case though, let's undo the change to ascending that broke the patch. :) Thanks!

amateescu’s picture

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

Rerolled for 8.2.x without any changes.

amateescu’s picture

And for 8.1.x with an underscore for the new method. @xjm, thanks for pointing out this underscore policy for BC, I didn't know about it :)

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 24: 2746033-24-8.1.x.patch, failed testing.

jhedstrom’s picture

Status: Needs work » Reviewed & tested by the community

Tests are passing, not sure why failure was indicated. Back to RTBC.

  • xjm committed a0fc0b0 on 8.2.x
    Issue #2746033 by amateescu, mohit_aghera, kamalrajsahu21, dawehner, xjm...
xjm’s picture

Status: Reviewed & tested by the community » Fixed

Thanks @amateescu!

I also tested this manually and confirmed that the revision page pager works as I would expect. (Had a revert-war with myself, since devel_generate seems not to allow generating revisions!)

Committed a0fc0b0 and pushed to 8.2.x and 58de4e7 to 8.1.x. Thanks!

  • xjm committed 58de4e7 on 8.1.x
    Issue #2746033 by amateescu, mohit_aghera, kamalrajsahu21, dawehner, xjm...

  • xjm committed a0fc0b0 on 8.3.x
    Issue #2746033 by amateescu, mohit_aghera, kamalrajsahu21, dawehner, xjm...

  • xjm committed a0fc0b0 on 8.3.x
    Issue #2746033 by amateescu, mohit_aghera, kamalrajsahu21, dawehner, xjm...

Status: Fixed » Closed (fixed)

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