Skip to content

Added typed resilient component specs with generated AP/KSP modules - #733

Open
GoodforGod wants to merge 4 commits into
masterfrom
feature/resilient-redesign
Open

Added typed resilient component specs with generated AP/KSP modules#733
GoodforGod wants to merge 4 commits into
masterfrom
feature/resilient-redesign

Conversation

@GoodforGod

@GoodforGod GoodforGod commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

EN

Improved Breaking: resilient AOP now uses typed component specs and generated AP/KSP modules instead of manager-based lookup by string name. This makes resilient components regular graph dependencies with typed config mapping and removes named/default config merging from the generated path.


RU

Переработана AOP-интеграция resilient-компонентов: вместо поиска через менеджеры по строковому имени теперь используются типизированные spec-интерфейсы и сгенерированные AP/KSP-модули. Resilient-компоненты стали обычными зависимостями графа с типизированной конфигурацией, без named/default config merging в сгенерированном пути.


  • Improved CircuitBreaker, Retry, Timeout, and RateLimiter AOP wiring to inject generated typed components instead of resolving them through managers.
  • Added AP/KSP generation of implementation classes and modules for declared resilient spec interfaces.
  • Removed generated usage of named manager APIs and default named config merging for resilient components.
  • Improved generated config handling so each spec maps directly from its declared config path.
  • Improved Fallback AOP by removing fallback spec/predicate components and invoking fallback methods directly with @Fallback.Reason.
  • Improved Java AP and KSP coverage for sync, async, suspend, Flow, and Kotlin typealias resilient targets.

Generated Component Shape

A declared spec interface becomes a generated implementation and module component.

@CircuitBreakerSpec("resilient.circuitbreaker.payment")
public interface PaymentCircuitBreaker extends CircuitBreaker {}

Representative generated module shape:

@Module
public interface $PaymentCircuitBreaker_Module {

    default CircuitBreakerConfig paymentCircuitBreaker_Config(
        Config config,
        ConfigValueMapper<CircuitBreakerConfig> mapper
    ) {
        return mapper.mapOrThrow(config.get("resilient.circuitbreaker.payment"));
    }

    default PaymentCircuitBreaker paymentCircuitBreaker_Impl(
        CircuitBreakerConfig config,
        @Nullable CircuitBreakerPredicate failurePredicate,
        CircuitBreakerTelemetryFactory telemetryFactory,
        ResilientConfig resilientConfig
    ) {
        var telemetryConfig = new CircuitBreakerOperationTelemetryConfig(
            resilientConfig.circuitBreaker(),
            config.telemetry()
        );
        return new $PaymentCircuitBreaker_Impl(
            "PaymentCircuitBreaker",
            config,
            failurePredicate,
            telemetryFactory,
            telemetryConfig
        );
    }
}

AOP Usage

Guarded methods now reference the typed component contract, and the aspect injects that component directly.

@CircuitBreaker(PaymentCircuitBreaker.class)
public String call() {
    return client.call();
}

For fallback, the fallback method receives the original failure through @Fallback.Reason.

@Fallback("fallback")
String call() {
    throw new IllegalStateException("failed");
}

String fallback(@Fallback.Reason RuntimeException reason) {
    return "fallback";
}

@GoodforGod GoodforGod added this to the v2.0.0 milestone Jul 17, 2026
@GoodforGod
GoodforGod requested a review from Squiry July 17, 2026 22:58
@GoodforGod GoodforGod added breaking change API breaking change module: resilient Related to Resilient module labels Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Test Results

140 tests   140 ✅  10m 41s ⏱️
  5 suites    0 💤
  5 files      0 ❌

Results for commit eccb305.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Dependency Update Report

Update level: patch

Found 3 dependency updates.

gradle/libs.versions.toml

  • s3client-aws (software.amazon.awssdk:s3, inline:248): 2.47.5 -> 2.47.6
  • zeebe: 8.9.12 -> 8.9.13
  • kotlin-stdlib: 2.4.0 -> 2.4.10

@GoodforGod GoodforGod changed the title [Draft] Added full-path CircuitBreaker components with generated factory modules [Draft] Added refactored and redesigned typed full-path CircuitBreaker Jul 19, 2026
@GoodforGod GoodforGod changed the title [Draft] Added refactored and redesigned typed full-path CircuitBreaker [Draft] Added typed resilient component specs with generated AP/KSP modules Jul 19, 2026
Added full config-path based CircuitBreaker wiring for annotation and symbol processors, replacing named manager lookup with generated tagged factory modules. Breaking: CircuitBreaker config is now resolved directly from the annotation path, with reserved root/telemetry paths rejected.

- Added generated path-based tags and modules that provide tagged CircuitBreakerFactoryModule instances and deduplicate shared config paths.
- Improved KSP CircuitBreaker AOP to inject tagged CircuitBreaker components directly and support suspend methods.
- Added CompletionStage and CompletableFuture CircuitBreaker coverage for Java AOP behavior.
Improved CircuitBreaker AP and KSP generation to use typed CircuitBreaker interfaces as injectable components, with config-bound generated implementations and modules.

- Added CircuitBreakable method annotation that injects the typed CircuitBreaker interface directly.
- Added interface-level CircuitBreaker generation for config, implementation, telemetry, and optional tagged predicate wiring.
- Improved failure predicate behavior so tagged CircuitBreakerPredicate overrides the interface test method, while the interface default is used when no predicate is provided.
- Removed path-based generated tags, CircuitBreakerFactoryModule, named failure predicate lookup, and old CircuitBreaker tag utilities.
Added Breaking: resilient components now use typed spec interfaces and generated modules instead of string-based named managers. CircuitBreaker, Retry, Timeout, and RateLimiter are created as regular graph components from their own typed configs, while Fallback is simplified to method-level fallback handling with explicit exception reason injection.

- Added typed spec annotations for CircuitBreaker, Retry, Timeout, and RateLimiter, with AP/KSP generation of implementation classes and module factories per declared spec interface.
- Removed named config/default config lookup flow and manager-based component resolution in favor of direct typed config mapping and generated graph components.
- Added Retry v2 behavior with optional exponential backoff, full jitter with ratio, and retry budget support.
- Added additional CircuitBreaker implementations and structured count-based/time-based configuration, including high-throughput variants for different accuracy/performance tradeoffs.
- Changed ResilientConfig to hold global telemetry defaults for all resilient components.
- Added per-component telemetry overrides that merge property-by-property with global telemetry config, matching SchedulingJobConfig-style behavior.
- Simplified Fallback by removing fallback predicates/spec components and routing failures to fallback methods with @Fallback.Reason exception arguments.
- Updated Java AP and KSP aspects/tests for sync, async, suspend, Flow, typealias, and generated component wiring.
@GoodforGod
GoodforGod force-pushed the feature/resilient-redesign branch from 9d7478e to eccb305 Compare July 20, 2026 01:12
@GoodforGod GoodforGod changed the title [Draft] Added typed resilient component specs with generated AP/KSP modules Added typed resilient component specs with generated AP/KSP modules Jul 20, 2026
@GoodforGod
GoodforGod marked this pull request as ready for review July 20, 2026 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change API breaking change module: resilient Related to Resilient module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant