Coming here from #993186: Node access rebuilds should go newest to oldest I was looking at the code in Drupal 8 for rebuilding nodes via a batch process. I have not tested it but it looks very broken - like someone made an attempt to improve the code along the lines of that issue at some point, but did so incorrectly.
Here's the code:
function _node_access_rebuild_batch_operation(&$context) {
if (empty($context['sandbox'])) {
// Initiate multistep processing.
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = \Drupal::entityQuery('node')->count()->execute();
}
// Process the next 20 nodes.
$limit = 20;
$nids = \Drupal::entityQuery('node')
->condition('nid', $context['sandbox']['current_node'], '>')
->sort('nid', 'DESC')
->range(0, $limit)
->execute();
$nodes = node_load_multiple($nids, TRUE);
foreach ($nodes as $nid => $node) {
// To preserve database integrity, only write grants if the node
// loads successfully.
if (!empty($node)) {
\Drupal::entityManager()->getAccessControlHandler('node')->writeGrants($node);
}
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $nid;
}
// Multistep processing : report progress.
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
So the first 20 nodes get processed in descending order: 20,19,18....1.
At the end of which, $context['sandbox']['progress'] is 20, and $context['sandbox']['current_node'] is 1.
Therefore, the next time through the batch, it will process these nodes: 21,20,19,18...2.
Oops, each node except the first is double-processed (and most are on their way to being processed 20 times).
But it's actually even worse, since $context['sandbox']['progress'] will be 40 after this second round, even though only 21 nodes have been processed. So it will eventually hit $context['sandbox']['max'] before all nodes have been processed, and the batch will finish with many nodes not rebuilt at all.
Again, I have not tested this so it's possible I'm missing something, but to me it looks like that's what will happen.
| Comment | File | Size | Author |
|---|---|---|---|
| #1 | node-access-rebuild-2331113-1.patch | 520 bytes | David_Rothstein |
Comments
Comment #1
David_Rothstein commentedHere's a simple patch - make the code go back to the way it worked in Drupal 7, and leave it to #993186: Node access rebuilds should go newest to oldest to figure out how to properly do it in descending order.
Probably there should be some kind of tests for this too.
Comment #2
David_Rothstein commentedAdding a related issue (although not the same as this one).
Comment #3
fabianx commentedWhat we have currently is totally broken, so lets get the Quick Fix in and improve upon it.
Comment #4
catchAgreed, this is a revert of a one-liner. I had a quick check to see if we could revert the original commit but it's far too long ago to do that.
Committed/pushed to 8.0.x, thanks!