Priorities

Many elements of an Infusion application (in particular, Listeners, Model Listeners, Options Distributions and Subcomponents) accept a standardised entry named priority which allows the position of that element within a list of similar elements to be adjusted. Depending on what the element is, the effect of the priority will be different — for example, a listener may be notified earlier or later than another listener, or a set of options or grades may take priority over another during options merging.

The priority system is designed to be "open" in the face of evolving application designs that are worked on by different groups. As well as standard fixed priorities (represented by numbers or extremal values such as "first" or "last"), Infusion priorities may be constraint-based in which an element defines its priority only with respect to another element which is identified by namespace. The syntax and idiom for namespaces follows that for event listeners. These constraint-based priorities are much less brittle than the use of fixed priorities, and are recommended whenever a priority directive seems to be required.

Supported values for priorities

Type Description Examples
Numeric An integer value representing a fixed priority (not generally recommended). In general, higher numbers represent "greater priority" with whatever meaning that takes in the relevant context. For example, a listener with higher priority will fire before one with a lower priority, or options with higher priority will merge on top of options with a lower priority1, 10, 100
Constraint Either of the strings before or after followed by the namespace of some other element (the "target element") of the same type, separated by a colon. The framework will sort all the elements in the same set so that this element will be placed immediately before or after the target element, unless a further constraint positions a third listener in between them."before:bindMarkup", "after:computeLayout"
Extremal Priority Either of the strings first or last, either by themselves, or followed by an extremal priority class (currently supported values testing and authoring) separated by a colon. Elements annotated first or last will sort either before or after all those which have been given finite numerical priorities (although a constraint-based priority will always have its directive honoured, even if it involves being situated beyond an element with extremal priority). If the string is followed by :class for one of the supported classes, this increases the "level of infinity" that the priority represents to that of the class, so that it will beat any extremal priority of a lower class or an unqualified extremal priority. The currently supported extremal priority classes are testing and authoring. So, an element listed last:authoring will beat an element listed last:testing, which will beat any element merely listed as last. "last", "last:testing"

Note that the framework's algorithm for sorting by priority uses a stable sorting algorithm so that in the absence of any priorities, any original ordering of the elements will be preserved. Elements without any priority will sort close to those which have been specified with an explicit numeric priority of 0, whilst retaining any original relative ordering. In the case of event listeners, this will be significant since it will respect any procedural order of addition, as well as any order resulting from grade merging. For options distributions, the natural ordering will be derived instead from the tree's topology (distributions which travelled a longer distance will be weaker than those which travelled a shorter distance), and numeric priorities should not be used.

Example of priority resolution for listeners

Here is part of a grade definition from the framework's Uploader component implementation, showing a recommended use of a constraint-based priority:

fluid.defaults("fluid.uploader.errorPanel.section", {
    gradeNames: ["fluid.viewComponent"],
...
    listeners: {
        "onCreate.bindHandlers": {
            funcName: "fluid.uploader.errorPanel.section.bindHandlers",
            priority: "before:refreshView"
        },
        "onCreate.refreshView": "{that}.refreshView"
    }
});

Amongst the two onCreate listeners, the framework guarantees that the bindHandlers listener will always be invoked before refreshView.

Table of supported sites for priorities and namespaces

The following table lists all the locations in component options where priorities are supported, together with some notes about their limitations and interpretation.

Options Record Entry Polarity Notes
listeners Lower numeric numbers, last, and after will fire later than others Full support for constraints, listeners uniquified based on namespace
modelListeners Ordering as for listeners. Model listeners will be sorted globally across the entire model skeleton by priority when a transaction concludes. Full support for constraints, model listeners uniquified based on namespace
modelRelay Ordering as for listeners. Model relay rules will be sorted locally at the point of responding to a model change within a transaction. Note that the same model relay rule(s) may operate multiple times within a transaction. Full support for constraints, model relay rules uniquified based on namespace
distributeOptions Lower numeric numbers, last and after will appear later in the merge order (with merging considering to occur from left to right — note that this is the opposite direction in which parent gradeNames of a grade are considered), that is, these will represent stronger options that will merge on top of other options. Full support for constraints, distributions not uniquified based on namespace (currently). Note that priority for distributions with the priority field left blank will be determined by component tree topology — distributions which travel a further distance will have weaker ("earlier", "lower") priority than distributions from nearby. Numeric priorities should not be used.
contextAwareness Supported in both adaptationRecord entries and checkRecord entries. In checks, lower numeric numbers, last, and after will be executed later than others. In adaptations, lower numeric numbers, last, and after will have their grades override those which appear before Full support for constraints, records uniquified based on namespace
components Ordering as for listeners. Components with lower priority will be constructed later. Note that there is no support for namespace for component declarations, and hence no support for constraint-based priorities. The use of priorities for subcomponent declarations is not recommended. You should always be able to rely on the natural data-driven (by order of resolving IoC references) order for instantiation of components.