[FLUID-6701] Idiom For Model Relay Transactions Interacts In A Faulty Way With Materialisation

by ADMIN 95 views

FLUID-6701: Idiom for Model Relay Transactions Interacts in a Faulty Way with Materialisation

Introduction

The Fluid Project's Infusion framework has been a cornerstone of web development for many years, providing a robust and flexible platform for building complex web applications. However, like any complex system, Infusion is not immune to issues and bugs. In this article, we will delve into the issue of FLUID-6701, which highlights a critical flaw in the transaction system of Infusion.

The Issue

When rewriting the textfield controls components to improve the handling of their validation, as described in the Bestiary of Reuse Failures, it was found that the transaction system for resolving model relays interacts in a faulty way with state held in "materialised" fields. This issue is particularly evident in the "Textfield Range Controller Tests: Test Negative Scale" test case.

The Problem

The test case sets up a textfield whose range is limited to [-15, -5], which is then supplied with an initial value of 0. The first firing of the validator, expressed as a classic "model relay to self," clamps this to the value -5. However, when the test case attempts to set the value of the text field to 56, the materialisation listener assigns 56 to "dom.container.value" via its binding. Unfortunately, this agrees with the value at the start of the transaction, and so as the transaction ends, no change at all is propagated out to the markup, which is left with the original value of 56.

The Root Cause

This issue suggests that the transactional system as a whole is basically flawed. The discussion in FLUID-6683 notwithstanding, the transactional system needs to become "progressive" to handle such scenarios. This had sort of been suggested by other user considerations, such as comparing Infusion's user characteristics with Boxer's. A system which responds to failures by simply "cancelling" the evidence of them is essentially user-hostile.

Proposed Solution

To rationalise this issue, we will attempt to package validation logic as a transforming promise chain, as an attempt to mock up the "vertical chains" system that we imagine being part of Infusion 6. This will involve using a plain modelListener with a priority of "last" to handle validation logic outside the transaction system.

Implementation

The proposed solution involves creating a transforming chain organised via priorities/namespaces with IoC-resolved arguments. This will allow us to express validation logic in a more modular and flexible way, making it easier to maintain and extend.

Conclusion

The issue of FLUID-6701 highlights a critical flaw in the transaction system of Infusion. By packaging validation logic as a transforming promise chain, we can create a more robust and user-friendly system that handles failures in a more progressive way. This proposed solution is a step towards creating a more modular and flexible framework that will be a cornerstone of web development for years to come.

Additional Context or Notes

Originally filed as FLUID-6701 by Antranig Basman on November 26, 2021.

Related Issues

  • FLUID-6683: Integral Bindings
  • FLUID-4982: Kulkarni Model* FLUID-6701: Idiom for Model Relay Transactions Interacts in a Faulty Way with Materialisation

Code Snippets

fluid.defaults("fluid.textfield", {
    gradeNames: ["fluid.viewComponent"],
    parentMarkup: true,
    modelRelay: {
        textfieldValue: {
            source: "dom.container.value",
            target: "value"
        }
    },
});

fluid.textfield.validateValue = function (that, value, oldValue) {
    var isNumber = !isNaN(Number(value));
    if (!isNumber) {
        that.applier.change("value", oldValue);
    }
};
fluid.textfieldSlider.validateValue = function (model, range, changeRequest) {
    var oldValue = model.value;
    var newValue = changeRequest.value;

    if (!isNaN(parseInt(newValue, 10))) {
        if (newValue < range.min) {
            newValue = range.min;
        } else if (newValue > range.max) {
            newValue = range.max;
        }
        changeRequest.value = Number(newValue);
    } else {
        changeRequest.value = oldValue;
    }
};
fluid.textfieldSlider.textfield.init = function (that) {
    that.applier.guards.addListener({path: "value", transactional: true}, function (model, changeRequest) {
        fluid.textfieldSlider.validateValue(model, that.options.range, changeRequest);
    });

    that.container.change(function (source) {
        that.applier.requestChange("value", source.target.value);
    });
};

References

  • Bestiary of Reuse Failures
  • New Notes on the ChangeApplier
  • FLUID-6683: Integral Bindings
  • FLUID-4982: Kulkarni Model
  • FLUID-6701: Idiom for Model Relay Transactions Interacts in a Faulty Way with Materialisation
    FLUID-6701: Idiom for Model Relay Transactions Interacts in a Faulty Way with Materialisation - Q&A

Introduction

In our previous article, we delved into the issue of FLUID-6701, which highlights a critical flaw in the transaction system of Infusion. In this article, we will answer some of the most frequently asked questions related to this issue.

Q: What is the root cause of the issue?

A: The root cause of the issue is that the transactional system as a whole is basically flawed. The discussion in FLUID-6683 notwithstanding, the transactional system needs to become "progressive" to handle such scenarios.

Q: What is the proposed solution to this issue?

A: The proposed solution involves packaging validation logic as a transforming promise chain, as an attempt to mock up the "vertical chains" system that we imagine being part of Infusion 6. This will involve using a plain modelListener with a priority of "last" to handle validation logic outside the transaction system.

Q: How will the proposed solution improve the user experience?

A: The proposed solution will improve the user experience by handling failures in a more progressive way. Instead of simply "cancelling" the evidence of failures, the system will now propagate changes out to the markup, making it easier for users to understand what is happening.

Q: What are the benefits of using a transforming promise chain?

A: Using a transforming promise chain will allow us to express validation logic in a more modular and flexible way, making it easier to maintain and extend. This will also make it easier to add new features and functionality to the system.

Q: How will the proposed solution affect the performance of the system?

A: The proposed solution will not affect the performance of the system in a significant way. The use of a transforming promise chain will actually make the system more efficient by reducing the number of unnecessary transactions.

Q: What are the next steps in addressing this issue?

A: The next steps in addressing this issue will involve implementing the proposed solution and testing it thoroughly. We will also need to make any necessary changes to the documentation and user guides to reflect the new functionality.

Q: How can I get involved in addressing this issue?

A: If you are interested in getting involved in addressing this issue, please contact the Infusion development team. We are always looking for volunteers to help with testing and implementing new features.

Q: What are the potential risks associated with this issue?

A: The potential risks associated with this issue are that the proposed solution may not fully address the underlying issues with the transaction system. However, we believe that the benefits of using a transforming promise chain outweigh the risks.

Q: What are the potential benefits of addressing this issue?

A: The potential benefits of addressing this issue are that it will improve the user experience, make the system more efficient, and provide a more modular and flexible way of expressing validation logic.

Q: What is the timeline for addressing this issue?

A: The timeline for addressing this issue is currently unknown. However, we are working to implement the proposed solution as soon as possible.

Q: How can I stay up-to-date with the latest developments on this issue?

A: You can stay up-to-date with the latest developments on this issue by following the Infusion development team on social media or by subscribing to our newsletter.

Q: What are the related issues to this one?

A: The related issues to this one are FLUID-6683: Integral Bindings, FLUID-4982: Kulkarni Model, and FLUID-6701: Idiom for Model Relay Transactions Interacts in a Faulty Way with Materialisation.

Q: What are the code snippets related to this issue?

A: The code snippets related to this issue are:

fluid.defaults("fluid.textfield", {
    gradeNames: ["fluid.viewComponent"],
    parentMarkup: true,
    modelRelay: {
        textfieldValue: {
            source: "dom.container.value",
            target: "value"
        }
    },
});

fluid.textfield.validateValue = function (that, value, oldValue) {
    var isNumber = !isNaN(Number(value));
    if (!isNumber) {
        that.applier.change("value", oldValue);
    }
};
fluid.textfieldSlider.validateValue = function (model, range, changeRequest) {
    var oldValue = model.value;
    var newValue = changeRequest.value;

    if (!isNaN(parseInt(newValue, 10))) {
        if (newValue < range.min) {
            newValue = range.min;
        } else if (newValue > range.max) {
            newValue = range.max;
        }
        changeRequest.value = Number(newValue);
    } else {
        changeRequest.value = oldValue;
    }
};
fluid.textfieldSlider.textfield.init = function (that) {
    that.applier.guards.addListener({path: "value", transactional: true}, function (model, changeRequest) {
        fluid.textfieldSlider.validateValue(model, that.options.range, changeRequest);
    });

    that.container.change(function (source) {
        that.applier.requestChange("value", source.target.value);
    });
};

Q: What are the references related to this issue?

A: The references related to this issue are:

  • Bestiary of Reuse Failures
  • New Notes on the ChangeApplier
  • FLUID-6683: Integral Bindings
  • FLUID-4982: Kulkarni Model
  • FLUID-6701: Idiom for Model Relay Transactions Interacts in a Faulty Way with Materialisation