Problem/Motivation
When there's a circular relationship between entity reference fields, the "gatsby_instantpreview" module will enter an infinite loop while saving the node. In the scenario where this was discovered, we had a content type which included taxonomy entity references, and those taxonomy terms had a computed field to display which content types referenced them. When saving one of the nodes that had a taxonomy term, an infinite recursion loop would be created.
Steps to reproduce
- Enable the gatsby_instantpreview module
- Create a new content type.
- Create an entity reference field on the content type that can reference the same content type.
- Go to the manage display tab of the content type and set the reference field to use the rendered entity display setting.
- Create a new node in this content type.
- Create a second node that references the first node.
- Edit the first node and set it to reference the second node.
- After re-saving the first node, the page should timeout due to the infinite loop caused by the circular references.
Proposed resolution
This appears to be caused by the `buildRelationshipJson()` method in the `GatsbyInstantPreview` class. At an initial read through it shouldn't be an issue, as there's a pass by reference `$entity_data` array that should be able to determine if a given entity has already been handled and exit early. However, that doesn't appear to be the case. I haven't done a deep analysis on why that's the case, but I have created a patch that adds an additional (optional) `$previous_items` array that behaves similar and will exit early.
Remaining tasks
Review the patch and investigate if an alternative solution should be used. One possible difference is that in my patch I'm updating the array prior to a continue statement that may be preventing the expected behavior otherwise.
User interface changes
n/a
API changes
n/a
Data model changes
n/a
Comment | File | Size | Author |
---|---|---|---|
#8 | 3175899-pass.patch | 2.61 KB | larowlan |
#8 | 3175899-fail.patch | 1.73 KB | larowlan |
| |||
#7 | 3175899-gatsby-preview-recursion-07.patch | 841 bytes | nickmans |
| |||
#4 | 3175899-gatsby-preview-recursion-04.patch | 1.42 KB | iansholtys |
#3 | 3175899-gatsby-preview-recursion-03.patch | 1.48 KB | Asacolips |
Comments
Comment #2
Asacolips CreditAttribution: Asacolips at Mediacurrent commentedComment #3
Asacolips CreditAttribution: Asacolips at Mediacurrent commentedRerolled the patch against the latest dev and refactored to clean up the approach a bit. This also resolves an error with buildRelationshipJson() being called elsewhere with two arguments instead of three.
Comment #4
iansholtys CreditAttribution: iansholtys at Mediacurrent commentedNoticed an issue with #3 when using fastbuilds.
The value was set to TRUE before checking to see if a valid entity could be loaded. If the uuid is "virtual", as can be seen with the parent relationship on a root-level taxonomy term, $entity_data will contain a mapping of 'virtual' to TRUE. Fastbuilds will include TRUE as one of the "data" objects, which doesn't make much sense.
Simple fix is to only add the placeholder after we know for sure it's actually an entity.
Comment #5
DamienMcKennaComment #6
larowlanComment #7
nickmans CreditAttribution: nickmans at The Reference commentedI think we can have an alternative approach much easier. I think that the logic is already implemented, but there's a bug. We should add the processed entity to the array before building the relationships.
Comment #8
larowlanHere's a test, interdiff is the fail patch
Comment #10
larowlanAs expected, the fail patch doesn't complete, it just loops endlessly
I killed it to save $$$ on drupalci.
Fixed on commit
Thanks all
Comment #12
teemuaro CreditAttribution: teemuaro commentedWe had the same issue with circular relationships with rc3. Updating to latest -dev fixed the issue that nodes are not saved, but caused a new problem that cloud builds are not triggered, with the error in logs
Notice: Undefined variable: preview_path funktiossa Drupal\gatsby_instantpreview\GatsbyInstantPreview->gatsbyPrepareData() (row 82 in file .../web/modules/contrib/gatsby/modules/gatsby_instantpreview/src/GatsbyInstantPreview.php)
Commenting out that row fixes the issue somewhat, but is of course not ideal. Now "normal", ie. nodes with no circular relationships save and trigger builds normally, but nodes with circular relationship save normally but don't trigger builds. This probably needs some work since row 82's $preview_path is never filled. Just removing it as per GatsbyPreview->gatsbyPrepareData didn't help either.
This might be related/caused by this? https://www.drupal.org/project/gatsby/issues/3204395
Comment #13
larowlanhi @teemuaro - could you open a new issue for that, sounds like it might be a recent change
Comment #14
teemuaro CreditAttribution: teemuaro commentedSure thing, thanks for the suggestion.
https://www.drupal.org/project/gatsby/issues/3212557