Uploaded image for project: 'Fluid Infusion'
  1. Fluid Infusion
  2. FLUID-5869

Error when reconstructing model relay component during existing transaction



    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0
    • Component/s: Data Binder
    • Labels:


      A complex scenario arising during implementation of the First Discovery preferences editor for PGA triggered an obnoxious bare diagnostic from the framework - within fluid.operateInitialTransaction , the line reading

                  shadow.modelComplete = true; // technically this is a little early, but this flag is only read in fluid.connectModelRelay

      produces a null reference error as the component "keyboardInput" has no shadow - since it has already been destroyed.

      Factors contributing to this failure are the following - firstly, "keyboardInput" is a createOnEvent component with the following definition

          fluid.defaults("gpii.firstDiscovery.panel.keyboard", {
              gradeNames: ["fluid.prefs.panel"],
              components: {
                  keyboardInput: {
                      type: "gpii.firstDiscovery.keyboardInput",
                      createOnEvent: "onInitInput",
                      container: "{that}.dom.input",
                      options: {
                          model: {
                              userInput: "{keyboard}.model.userInput",
                              stickyKeysEnabled: "{keyboard}.model.stickyKeysEnabled"
                          messageBase: "{keyboard}.options.messageBase"
              listeners: {
                  "afterRender.relayEvents": {
                      funcName: "gpii.firstDiscovery.panel.keyboard.relayEvents",
                      args: ["{that}"]

      is fired by the following definition:

          gpii.firstDiscovery.panel.keyboard.relayEvents = function (that) {
              var offerAssistance = that.model.offerAssistance;
              if (offerAssistance !== false) {
                  if (offerAssistance) {

      The problem here is that the construction of the keyboardInput component, by virtue of setting up a fresh model relay and init transaction, is capable of "self-reacting" with respect to this definition - triggering a change to the model and refreshView call, whilst still on the same event stack as the original model change (and, by extension, the init transaction associated with the PREVIOUS instance of the keyboardInput component). This creates complete chaos with our current model, that assumes that only one init transaction can be in progress across the component tree at a given moment (clearly a faulty assumption, but one of the few reasonable ones under the "old ginger" model where a fresh participant in the transaction could be discovered at any time). Inspection of "modelTransactions" shows a huge number of transaction elements in progress at the same moment, including participants of both the old and new instance of "keyboardInput".

      Removing the "stickyKeysEnabled: "


      .model.stickyKeysEnabled"" definition seems to make no difference to the outcome.

      This is a case which, under the current model relay implementation, we have little choice but to consider in error, and just issue the best diagnostic as early as we can. Until we have the global reimplementation coming as part of FLUID-4982, we can't do much better. In that world, at least we can expect to have multiple, non-interfering init transactions. However, the more fundamental issue here is the lack of implementation feature "lensing components into existence" envisioned as the final implementation stage of the "new renderer". The problem is that the action of the system "hops out" of the model transaction and then attempt to "hop back" in again as a result of listening to the refreshView action triggered by it. Clearly all of this activity really is part of the same transaction and there should be a way of expressing it so it is so. The FLUID-5865 work will bring this one step closer, but until we have a relay equivalent of the "createOnEvent" directive the gap will remain unbridgeable.




            antranig Antranig Basman
            antranig Antranig Basman
            0 Vote for this issue
            1 Start watching this issue