I've tried to enable Diff module and the code went to loop. This also happening when I'm doing feature-update from drush.
It's just rebuilding caches over and over again and the code goes over 5000 levels deep.
Here is the main issue:
17.7711 297204736 14. entity_flush_caches() includes/module.inc:934
17.7830 281430864 15. entity_defaults_rebuild($entity_types = ???) entity/entity.module:1085
57.1516 335722104 16. _entity_defaults_rebuild($entity_type = 'rules_config') entity/entity.module:857
58.2322 401386312 17. entity_delete($entity_type = 'rules_config', $id = 'rules_foo') entity/entity.module:898
58.2322 401386680 18. entity_delete_multiple($entity_type = 'rules_config', $ids = array (0 => 'rules_applicant_rule_somebody_else')) entity/entity.module:316
58.2323 401387000 19. RulesEntityController->delete($ids = array (0 => 'rules_foo'), $transaction = ???) entity/entity.module:338
58.2359 401387744 20. EntityAPIControllerExportable->delete($ids = array (0 => 'rules_applicant_rule_somebody_else'), $transaction = class DatabaseTransaction { protected $connection = class DatabaseConnection_mysql { ... includes/rules.core.inc:276
58.2551 401399872 21. entity_defaults_rebuild($entity_types = array (0 => 'rules_config')) entity/includes/entity.controller.inc:890
So basically entity_defaults_rebuild()
is called first from entity_flush_caches()
, then while rebuilding, it's calling again entity_defaults_rebuild()
on Entity delete.
Affected code:
entity.module
function entity_flush_caches() {
entity_property_info_cache_clear();
// Re-build defaults in code, however skip it on the admin modules page. In
// case of enabling or disabling modules we already rebuild defaults in
// entity_modules_enabled() and entity_modules_disabled(), so we do not need
// to do it again.
// Also check if rebuilding on cache flush is explicitly disabled.
if (current_path() != 'admin/modules/list/confirm' && variable_get('entity_rebuild_on_flush', TRUE)) {
entity_defaults_rebuild();
}
...
which triggers code in includes/entity.controller.inc on RulesEntityController->delete()
:
public function delete($ids, DatabaseTransaction $transaction = NULL) {
$entities = $ids ? $this->load($ids) : FALSE;
if ($entities) {
parent::delete($ids, $transaction);
foreach ($entities as $id => $entity) {
if (entity_has_status($this->entityType, $entity, ENTITY_IN_CODE)) {
entity_defaults_rebuild(array($this->entityType)); // HERE!!!
break;
}
}
}
}
And this goes endlessly on each entity_flush_caches()
.
Comment | File | Size | Author |
---|---|---|---|
#12 | entity-rebuild-loops-2698553-12.patch | 642 bytes | james.williams |
| |||
#6 | d7_rules.bt_.dump_.txt.gz | 162.38 KB | kenorb |
Issue fork entity-2698553
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
kenorb CreditAttribution: kenorb commentedTested patch from #1993818: entity_delete() should check for the presence of a delete() method on the entity class, but it didn't help.
Comment #3
kenorb CreditAttribution: kenorb commentedComment #4
kenorb CreditAttribution: kenorb commented#2229625: Fields are NOT ALWAYS being deleted when deleting exported bundle entities
Comment #5
kenorb CreditAttribution: kenorb commentedComment #6
kenorb CreditAttribution: kenorb commentedI'm having 750 rules to feature-update. Increasing `xdebug.max_nesting_level` to 512, 1024, 2048 or 4096 didn't help. See the backtrace dump in the attachment.
Comment #7
kenorb CreditAttribution: kenorb commentedIt sounds that I needed ~6 levels for each rule, so over 5000 levels deep potentially should be enough. Increased max_nesting_level to 6000, however some other modules (commerce_ss) got involved:
and I think at some point went further (without stopping with the error), but started heavily processing feature-update for the few hours or so (I had to stop it).
Comment #8
kenorb CreditAttribution: kenorb commentedComment #9
kenorb CreditAttribution: kenorb commentedWorkaround is to set variable entity_rebuild_on_flush to FALSE (e.g.
drush vset entity_rebuild_on_flush FALSE
), to explicitly disable rebuilding defaults on cache flush.Comment #10
kenorb CreditAttribution: kenorb commentedComment #11
BR0kENThis error also valid for another scenario:
Comment #12
james.williams CreditAttribution: james.williams at ComputerMinds commentedI ran into this kind of issue because I removed a commerce discount offer type, so suddenly lots of discounts needed removing. Discounts are implemented by commerce_discount as rules (which are entities) in its default hook, so they all have the 'in code' status. During the first rebuild, on removing the first discount,
entity_defaults_rebuild()
is called, despite being in the middle of a rebuild. I can see that a rebuild would be necessary if truly reverting an entity that was in the database, to its definition in code, but if it is being deleted during a rebuild, there's really no need to rebuild again at that point.This attached patch avoids rebuilding in the middle of a rebuild. I can't guarantee this is the best approach, or that it will actually fix anyone else's problem, but someone that knows the entity module better than me might be able to confirm this makes sense to do in general. It may well help lots of people, who knows!
Comment #13
Steven Jones CreditAttribution: Steven Jones at ComputerMinds commented@james.williams thanks so much for your patch. I was trying to change something about commerce shipping services and that was causing and infinite loop that led me to this issue. I've applied the patch it solves the issue perfectly. Given that
_entity_defaults_rebuild
goes to the trouble of setting->is_rebuild
on the entity it makes sense to me to check that flag before performing another rebuild.It uses it for the
\EntityAPIControllerExportable::save
method already so why not use it in the delete method too.Comment #16
VladimirAusCreated MR.