Status: Pull Request
Affects Version/s: None
Fix Version/s: None
Component/s: IoC System
In fixing a test case for the rewritten Table of Contents component using the new renderer, the following construct caused an error:
The call to "refetchOneResource" triggers the construction of further lensed components corresponding to the markup freshly added to the page, i.e. from
This exposes an error in the "ModelComponentQix" in a similar way to that reported in FLUID-6406. The failure received is in fluid.enlistModelComponent for the nested link subcomponent -
On the first line, we find that no model transaction is in progress. This is because of a fault in the implementation of fluid.applyWorkflowPhase which currently reads:
The error is in the assumption of the first block - that any freshly created shadows can be brought to the level of the most advanced. In this case, since we are still within "onCreate", the existing transaction has not yet concluded, and we have a whole collection of components which have reached the final workflow stage (in this configuration, numbered 8).
We receive the construction of the "level" component as a fresh potentia, but it is not appropriate to bring it to the same level 7 as the rest of the transaction in one step because of its own potential to lens further components into existence at workflow stages 0 and 3. For reference, the current workflow cache looks as follows:
Why did we implement fluid.applyWorkflowPhase in this way? It is to simplify its record-keeping in order to consider that the workflow progress at any point can be described by two numbers, the width of an initial single "step" and its height. In this way we avoid complex dynamic allocations to track the workflow progress or expensive scans of progress to find the next work item.
However, the fact that components may be created at stage 7 and then cascade down to further creations and lower stages shows that this simple "Qix" geometry is inadequate. We have a couple of ways out -
i) Discard the entire transaction at the end of a block of onCreate and start a fresh one - pretty distasteful and will create a lot of upheaval in what is now moderately settled code.
ii) Go towards a more complex "chain of blocks" representation of Qix progress
iii) Special-case this situation and add a further integer to Qix tracking which creates a "horizon" ignoring components which have reached concludeComponentInit, and reset lastWorkflowShadow to 0. This is a kind of "lite" version of option i).
Note that we are already special-casing components reaching concludeComponentInit by means of this signalling from fluid.enqueueWorkflowBlock:
This signalling reaches fluid.commitPotentiae and becomes a further case in which a fresh "sequencer" should be constructed:
Presumably the thinking here is that if we have once "started" to issue concludeComponentInit, the top sequencer is going to receive resolution by the time the stack frame returns. It seems that we should, as usual, somewhat abandon the pretence that this is a general-purpose algorithm, although its structure seems to peculiarly recur throughout the design of the system.
In a side note, the huge garbage and stack noise we see amongst these sequencers suggest that we should abandon the use of promises in favour of a "heap o' records" approach. It's unclear that async/await will help with this because these constructs intrinsically appeal to the creation and destruction of promises.