Skip to content
Modules

Core

Core Modules

Three modules form the non-negotiable foundation of every Failover installation: failover-domain, failover-core, and failover-aspect.


failover-domain

Provides the @Failover annotation and the two contracts for marking your domain types:

Type Kind Purpose
@Failover Annotation Declares failover behaviour on a method
Referential Abstract class Extend to add upToDate, asOf, metadata fields
ReferentialAware Interface Implement when inheritance is not possible
Metadata Class Key/value carrier for optional context in Referential

Add this to any module that annotates methods or defines referential domain types:

<dependency>
    <groupId>com.societegenerale.failover</groupId>
    <artifactId>failover-domain</artifactId>
    <version>3.0.0</version>
</dependency>

failover-core

Provide an SLF4J logging implementation

failover-core depends on slf4j-api for logging but does not bundle any SLF4J implementation. Spring Boot users get Logback automatically via spring-boot-starter-logging. Without Spring Boot, add one explicitly:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j2-impl</artifactId>
</dependency>

Contains all SPI interfaces and their default implementations:

Interface Default implementation Purpose
FailoverHandler<T> DefaultFailoverHandler Store/recover/clean orchestration
FailoverStore<T> DefaultFailoverStore (delegates to impl) Persistence contract
KeyGenerator DefaultKeyGenerator Raw key from method args
ExpiryPolicy<T> DefaultExpiryPolicy TTL computation and check
PayloadEnricher<T> DefaultPayloadEnricher Enrich on store/recover
PayloadSplitter<T,R> (none — must provide your own) Scatter/gather split/merge
RecoveredPayloadHandler (none — null by default) Handle null recovery result
ContextPropagator CompositeContextPropagator(noOp) Thread context across async slices
FailoverScanner SpringContextFailoverScanner (in failover-scanner) Discovers @Failover methods and their payload types

All beans use @ConditionalOnMissingBean in auto-configuration — declare your own @Bean to replace any default.

Scanner SPI package

FailoverScanner lives in com.societegenerale.failover.core.scanner (moved from core.observable.scanner in 3.0.0). It is a neutral shared component: observability reporting consumes the discovered annotations, and the JDBC store consumes findAllPayloadTypes() to build its deserialization allowlist. See ADR 42.

Handler Decorator Chain

flowchart TD
    A[AdvancedFailoverHandler] --> S[ScatterGatherFailoverHandler]
    S --> D[DefaultFailoverHandler]
  • AdvancedFailoverHandler — adds metrics publishing and RecoveredPayloadHandler invocation.
  • ScatterGatherFailoverHandler — intercepts when payloadSplitter is set; delegates directly to DefaultFailoverHandler for plain failovers. A thin facade over package-private collaborators — PayloadScatter (store side), PayloadGather (recover side), SliceDispatcher (parallel/sequential dispatch + per-slice timeout) and SplitterInvoker (splitter lookup and invocation). See ADR 49.
  • DefaultFailoverHandler — core key/expiry/store/recover logic.

For the full store / recover / clean invocation order (and how it maps to the auto-configuration bean wiring), see How It Works — Handler Chain and Execution Order.


failover-aspect

Contains FailoverAspect, a Spring AOP @Around advice:

@Around("@annotation(failover)")
public Object failoverAround(ProceedingJoinPoint pjp, Failover failover) throws Throwable { /*...*/ }

The aspect:

  1. Resolves the annotated method's @Failover metadata and the reflected Method.
  2. Hands off to FailoverExecution.execute(failover, supplier, method, args), which proceeds (calls upstream).
  3. On success: FailoverExecution calls failoverHandler.store(failover, method, args, result).
  4. On exception: FailoverExecution calls failoverHandler.recover(failover, method, args, clazz, cause), then MethodExceptionHandler applies the exception policy.

FailoverExecution is the thin wrapper that selects between BASIC (try/catch) and RESILIENCE (circuit-breaker) modes.


failover-store-inmemory

ConcurrentHashMap-backed store. Zero dependencies. Used as the default store when no other store module is on the classpath.

Not for production

InMemory store is not persistent. All cached data is lost on restart.


Next Steps