Lifecycle
Lifecycle groups three actions:
Lifecycle.of(String name, Action before, Action main, Action after)
Semantics
Execution order is always:
beforemainor a recursive skip ofmainafter
Important behavior from the current implementation:
afteralways runs- if
beforefails,mainis skipped - if
beforeskips,mainis skipped - if
mainfails, the lifecycle fails - if
mainskips, the lifecycle skips unlessafterfails - if
afterfails, the lifecycle result becomesFAIL
Context hierarchy
before and after share the same lifecycle child context.
main runs in a child of that lifecycle context.
That means data attached in before is usually read from main via context.findContext(1) or context.findAttachment(1).
When main is skipped (because before failed or skipped), each skipped action and its descendants receive their own child contexts, mirroring the action tree. Listener callbacks interleave the same way as normal execution: parent beforeAction, then children, then parent afterAction.
Example
Pattern used in examples/test/lifecycle/FullLifecycleTest.java:
Action suite = Lifecycle.of(
"suite",
Direct.of("before", context -> context.setAttachment("ready")),
Direct.of("main", context -> {
String value = context.findAttachment(1)
.flatMap(a -> a.to(String.class))
.orElseThrow();
}),
Direct.of("after", context -> context.removeAttachment()));
Cleanup note
Lifecycle itself does not attach suppressed exceptions to earlier failures. If you need aggregated cleanup failures, use Cleanup.