Sequencing in NDMF determines the execution order of plugin passes. This is achieved through a combination of Phases and Constraints.
The Execution Model
Execution is organized as a tree where Phases are nodes and Passes are leaves. Each phase has its own independent dependency ordering.
Constraint Types
Constraints allow plugin authors to express ordering requirements. They are ranked by "binding strength":
- After (runs-soon-after): A strong constraint requiring a pass to run as soon as possible after another. Only one
After constraint can be specified per target pass. - Successor constraints: Internally defined by the order in which passes are declared within a phase. If no
After constraint intervenes, the framework prefers to run the next declared pass immediately after the current one. - NotBefore / NotAfter: Declares that one pass must run after/before another, but without a strong preference for how quickly it happens. These are converted into topological sort requirements.
Constraint Scopes
Constraints are phase-local. This means:
- Pass/Phase targets: Must exist within the same parent phase.
- Plugin targets: Constraints applied to a plugin (e.g.,
.AfterPlugin("name")) apply to all passes or phases belonging to that plugin within the same phase. - Successors: Only generated between passes in the same phase.
If you need to enforce an order across different phases, you cannot use standard constraints; you must ensure the logic is handled via the phase hierarchy or by declaring a pseudopass that bridges the requirements.
// Example of the hierarchy:
// Phases (Nodes) -> Passes (Leaves)
// Constraints are applied within the scope of a Phase.