Hi all, I started looking into how to implement shouldRunAfter task ordering rule. Some time ago Adam wrote:
The idea is to add a very weak task execution rule that only provides hints > for execution order and implies nothing else. So, if A shouldRunAfterB > then: > > 1. If A or B are not scheduled to run, ignore the rule. > 2. Run A after B only if there are no other contradictory rules on the > ordering of A and B. That is, ignore cycles introduced by shouldRunAfter > rules. > 3. The dependencies of A shouldRunAfter B and its dependencies. > 4. If B fails or is not run, A can still be run. > 5. If there is an idle worker thread and A is the only task whose > dependencies have been satisfied, then run A regardless of whether B has > beenrun or not. That is, prefer running the task over an idle worker > thread. > > Similar to mustRunAfter, but different in #2 and #5 above. > #1, #3 and #4 are straightforward. With regards to #2 the idea is to: - at the beginning of DefaultTaskExecutionPlan.determineExecutionPlan() find all cycles in the execution graph using CachingDirectedGraphWalker the same way as in onOrderingCycle() - find the first cycle that has no shouldRunAfter edges and throw a CircularReferenceException - if no such cycles are found iterate over all cycles and for each remove the first found shouldRunAfter edge (possibly with some logging?) - this will break the cycle; it's possible that a cycle won't have a shouldRunAfter edge as some cycles may share a shouldRunAfter edge that has been already removed but because we checked for cycles without shouldRunAfter edges before we know that all cycles in this phase had such edge at one point - continue with execution plan determination The downside here is that we would be adding another graph traversal to the process. On the other hand I don't see how we could detect and break cycles with shouldRunAfter edges in them without doing so. With regards to #5, do I understand correctly that it simply means that shouldRunAfter ordering should not be treated as a dependency in context of TaskInfo.allDependenciesComplete()? Marcin