A typical art framework job configuration might look like:
physics: {
producers: {
p1: {}
p2: {}
p3: {}
}
filters: {
f1: {}
}
analyzers: {
a1: {}
a2: {}
}
# Trigger paths
tp1: [p1, p3]
tp2: [f1, p2]
# End paths
ep1: [a1, o1]
ep2: [a2, o2]
}
outputs: {
o1: {}
o2: {}
}
where the specific configurations for the modules have been suppressed. For such a configuration, the following behaviors apply:
tp1 and tp2) are executed is unspecified in single-threaded art. In multi-threaded art, trigger paths will be executed concurrently.There are two kinds of dependencies between modules to consider: data-product dependencies and filter-module dependencies.
As an example, suppose that filter f1 depends on a data product pr1 that has been produced by the producer p1. Because of behavior 1, in the configuration above it is not guaranteed that the pr1 product will be available by the time f1 processes the event. Because of this, the above configuration is ill-defined in single-threaded art, despite the current event-processing implementation executing trigger paths in alphabetical order according to the trigger-path name. A change as simple as relabeling the paths can affect the output. In multi-threaded art, such a configuration is illegal.
The solution to this problem (in both single-threaded and multi-threaded art) is to list the p1 producer as the first module in path tp2:
tp1: [p1, p3]
tp2: [p1, f1, p2]
With this configuration, the producer p1 is guaranteed to execute before the filter f1, and art ensures that a module shared across paths (i.e. p1) is executed only once.
There is another dependency that can cause processing surprises. Consider the following trigger-path specifications:
tp1: [p2]
tp2: [f1, p2]
This configuration represents a potential mistake: in path tp1, p2 is to be unconditionally executed, whereas in path tp2, it is to be executed if the event passes filter f1. Although this is not an error per se, it may not be what is intended. Users should be wary of such configurations.
Consider the situation where the producer p3 consumes product pr1 created by producer p1. In such a case, the following configuration is an error:
tp: [p3, p1]
Because of behavior 2 above, p3 will execute before p1, and pr1 will not be available. This configuration error has not been caught in the past, but if the user invokes the consumes API, such an error can be caught by the framework.
The corresponding rule is:
art::Event::getManyIn current versions of art, and for art 3.0, the behavior of getMany will be to return any products in memory that match the given criteria. In future versions of art (not art 3.0), this behavior will be restricted so that the only products returned to the user will be those matching the given criteria for (a) modules on that path and (b) any products provided by the source. Consider the following configuration:
tp1: [p1, p2, p3, p6]
tp2: [p1, p2, p4, p5]
If module p6 calls Event::getMany, then any products produced by modules p1, p2, and p3, are candidates for being provided to p6. art would guarantee that any products produced by p4 and p5 would not be provided during the getMany call, even if p4 and p5 happened to executed before p6.
getManyConsider this configuration:
tp1: [p1, p2, p3]
tp2: [p4, p5, p3]
What should the expected behavior of getMany be in this case?