Problem/Motivation
I just updated to beta3 and when moving elements around slots, I often (not always) get and error. I need to go back to the last saved version and try again. I don't see a error in the drupal log.
[attachToRoot] moveToRoot failed with invalid data
Array
(
[node_id] => 69a81ecc57b6d
[position] => 9
[ajax_page_state] => Array
(
[theme] => hda_theme
[theme_token] => null
)
)
Steps to reproduce
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #7 | video_3576984.mp4 | 4.23 MB | mogtofu33 |
Issue fork display_builder-3576984
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
pdureau commentedHi, thanks for your ticket.
Can you provide a way to reproduce the issue? You said it happens often to you, maybe there is a pattern to identify here.
Comment #3
mogtofu33 commentedI can reproduce, seems there is a problem with our changes on moveToSlot.
The message is wrong because of a wrong copy, will fix on this MR to have proper message.
From new instance
Sometimes it can occur without textfield, just moving around same 2 components in a slot, move order or in and out.
Comment #4
mogtofu33 commentedRemoved librairies data from issue error message, it's not relevant.
Comment #5
mogtofu33 commentedComment #6
mogtofu33 commentedI have the error from $data = NestedArray::getValue($root, $path);, when the error occur, $data is null.
At some point when moving around from one slot to another, $root start on index 1 instead of 0, the 0 index is strangely removed.
Comment #7
mogtofu33 commentedComment #9
mogtofu33 commentedComment #10
pdureau commentedComment #11
mogtofu33 commentedLooks good, removed some InstanceHistoryTest for now as they were not relevant.
I still ave a problem with
testMoveFromComponentToNestedLayoutEmptyRegion(), @pdureau could you check?Comment #12
pdureau commentedI see you are unifying the move to same slot and different slot by removing
::isNodeAlreadyInSlot(),::changeSourcePositionInSlot()and::doMoveToSameSlot(). that's very cool.Indeed, the test is skipped and fails if executed:
Step 1
This phpunit fails is not the real issue. First, we need to adapt the test to the new logic which is rebuilding the index during the
moveToSlot()(maybe not at the right moment, but we will see later).I have pushed a commit in a side branch: https://git.drupalcode.org/issue/display_builder-3576984/-/commits/35769...
Step 2
Now we have the real issue:
And we see the source we are moving around has disappeared from the source tree!
The first
moveToSlotis chaining:The second
moveToSlotis chaining:doUpdateSlotValue()is not executed because the parent data is not found. That's weird because when i check, i found the expected data.Step 3 ?
I guess we may have an other issue here because we are rebuilding the index in a "Internal atomic change of the root state." method.: at the last line of
::doUpdateSlotValue()In my opinion, this must not happen. It is better to chain the "internal atomic changes of the root state" consistent indexes with and altered but not rebuilt index. Before and/or after those steps, it is OK to rebuild the index.
We may be safe here because
::doUpdateSlotValue()is the last step of the chain, so rebuilding the index is not messing with next steps, but I am afraid it is not future proof.What can we do to be 100% safe and make this clear for next updates? What do you think about moving the atomic methods to a tiny utility class:
Does it makes sense?
Comment #13
mogtofu33 commentedI am full for moving this data tree manipulation to it's own class, I am starting that on a new branch.
Comment #17
mogtofu33 commentedAdded a class, we store a 'simple' tree now with only ids to have something lighter and a flat list of source values by ids.
The sources 'layout' and 'page_layout' with their 'regions' brings some complexity for nothing, would be great if they match the 'component' slots.
For now I probably removed the case of move to the same place, but it's more important to resolve the current bug.
Comment #20
pdureau commentedThey will not, unfortunately. Component slots were badly modeled (unexpected "component" and "sources" levels) when we built UI Patterns 2 in 2024 and we must deal with legacy until at least UI Patterns 3.
Which case exactly? Moving a source to the same slot but at a different position ? This is a very common action.
The actual SourceTree in the MR doesn't meet the target in my opinion:
SDC slot manipulation is hardcoded in the logic, back to the situation before beta2 and
SourcewithSlotInterface:So we are increasing coupling here where the opposite was expected.
I see the commit has been merged while being assigned to me for review. It is not common for me to ask such a thing but, considering the situation, I think we must revert it and start again from 3576984-attachtoslot-failed or 3576984-attachtoslot-failed-pierre
Comment #21
pdureau commented(misclick)
Comment #23
pdureau commentedI have pushed an additional commit to the previous branch 3576984-attachtoslot-failed_pierre with a proposal of what could be such a utility class:
The idea is to make every manipulation of the source tree as safe as possible, so each operations are moved there, in a totally stateless logic, with a total data consistency from the first step to the last, and easily testable with Unit Tests.
So, no index manipulation, no history awareness. Every method get a source tree as
$rootand returns the altered source tree and nothing else.We can now mess around in Instance entity, with the business logic, the entity & CMS logic, the history logic, and the stateful index, without never ever breaking the source tree.
By the way, the remaining issue ("Failed asserting that a NULL is not empty" in
InstanceMoveToSlotTest::testMoveFromComponentToNestedLayoutEmptyRegion) seems to be fixed now 😉The pipeline is green ✅If you like this, we can move on together:
\assert()in the beginning of each methods?::getSlotSourcePlugin()public in order to avoid duplication in Instance ?Also, not related to
SourceTreeAtomicOperationsbut to previous works. Many tests have been removed fromInstanceHistoryTest:::testClear(),::testRedo(),::testHashDuplicateDetection(),::testSetNewPresent(),::testUndo(). Is it normal?Comment #26
mogtofu33 commentedComment #27
mogtofu33 commentedSeems there is other problems introduced...
I am going back to my branch SourceTree that resolve the issue, was fully covered by Unit tests and was totally isolated without any service injection.
Comment #31
mogtofu33 commentedComment #32
mogtofu33 commentedComment #33
pdureau commentedHi Jean, do you want me to review?
Comment #34
mogtofu33 commentedComment #35
pdureau commentedDoes that means the root cause was #3540701: Wrong event triggered by ApiController::attachToSlot() since the beginning and there was nothing wrong with the current logic in Instance? 🙃 If yes, let's close the other issue as "duplicate" or "outdated".
That doesn't mean the current MR doesn't worth the hard work because:
OK for me because:
Comment #37
mogtofu33 commented