Install
$ agentstack add skill-kora-projects-kora-skills-kora-aop-resilient ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Kora AOP Resilient
Compile-time AOP annotations for fault tolerance: @Retry, @CircuitBreaker, @Timeout, @Fallback. They are generated into $__AopProxy classes at build time — no reflection. Provided by the resilient-kora module via ResilientModule.
Quick Navigation:
- [Quick Start](#quick-start) — get running in four steps
- [Combined Pattern](#combined-resilience-pattern) — stack all annotations on one method
- [References](#references) — per-aspect deep dives
Quick Start
1. Add the dependency and annotation processor
dependencies {
// All Kora artifacts inherit their version from the kora-parent BOM — never pin them individually.
annotationProcessor "ru.tinkoff.kora:annotation-processors" // mandatory: generates the AOP proxies
implementation "ru.tinkoff.kora:resilient-kora"
}
> Kotlin uses ksp "ru.tinkoff.kora:symbol-processors" instead of annotationProcessor.
2. Enable ResilientModule
@KoraApp
public interface Application extends
HoconConfigModule,
LogbackModule,
ResilientModule { } // enables the resilience aspects
3. Apply Resilience Annotations
Each annotation lives in its own package:
| Annotation | Import | |------------|--------| | @CircuitBreaker | ru.tinkoff.kora.resilient.circuitbreaker.annotation.CircuitBreaker | | @Retry | ru.tinkoff.kora.resilient.retry.annotation.Retry | | @Timeout | ru.tinkoff.kora.resilient.timeout.annotation.Timeout | | @Fallback | ru.tinkoff.kora.resilient.fallback.annotation.Fallback |
@Component
public class PaymentService { // MUST be non-final (Java) / open (Kotlin) for aspects to apply
@Fallback(value = "payment.process", method = "processFallback(request)")
@CircuitBreaker("payment.process")
@Retry("payment.process")
@Timeout("payment.process")
public PaymentResult process(PaymentRequest request) {
return paymentGateway.charge(request);
}
protected PaymentResult processFallback(PaymentRequest request) {
return PaymentResult.pendingManualReview();
}
}
The annotation value is a config key, not a shared identifier — @Retry("payment.process") reads resilient.retry."payment.process". Different aspects on the same method may use independent keys.
4. Configure Resilience
resilient {
timeout {
default { duration = "1s" }
"payment.process" { duration = "5s" }
}
retry {
default {
delay = "100ms"
attempts = 3
delayStep = "100ms"
}
}
circuitbreaker {
default {
slidingWindowSize = 100
minimumRequiredCalls = 10
failureRateThreshold = 50
waitDurationInOpenState = "30s"
permittedCallsInHalfOpenState = 5
}
}
fallback {
default { enabled = true }
}
}
> Important: Use minimumRequiredCalls (NOT minimumNumberOfCalls) — Kora-specific key.
Combined Resilience Pattern
Recommended order (outer → inner):
@Component
public class PaymentClient {
// Order (outer → inner):
// 1. @Fallback — degraded response if everything fails
// 2. @CircuitBreaker — fail fast if repeatedly failing
// 3. @Retry — retry transient failures
// 4. @Timeout — bound each attempt
@Fallback(value = "payment.charge", method = "chargeFallback(request)")
@CircuitBreaker("payment.charge")
@Retry("payment.charge")
@Timeout("payment.charge")
public PaymentResult charge(PaymentRequest request) {
return httpClient.post("/payments", request);
}
protected PaymentResult chargeFallback(PaymentRequest request) {
return PaymentResult.pendingManualReview();
}
}
Execution flow:
@Timeoutbounds the actual HTTP call@Retryrepeats on transient failures (up to N attempts)@CircuitBreakeropens if failures exceed threshold@Fallbackreturns degraded response if circuit is open or all retries fail
References
Detailed guides with configuration options, patterns, and examples:
| Reference | Description | |-----------|-------------| | [retry-reference.md](references/retry-reference.md) | @Retry, predicates, backoff patterns, wait time calculation | | [circuit-breaker-reference.md](references/circuit-breaker-reference.md) | @CircuitBreaker, state machine (CLOSED/OPEN/HALF_OPEN), custom predicates | | [timeout-reference.md](references/timeout-reference.md) | @Timeout patterns, per-attempt vs overall timeout, thread interruption | | [fallback-reference.md](references/fallback-reference.md) | @Fallback methods, signature rules, fallback patterns | | [resilience-config-reference.md](references/resilience-config-reference.md) | Full configuration reference, custom predicates, high-throughput tuning |
Supported Signatures
Java
Class must be non-final for AOP to work.
| Return Type | Example | |-------------|---------| | T (or Void) | User getUser(String id) | | Optional | Optional getUser(String id) | | Mono / Flux | Project Reactor types (require io.projectreactor:reactor-core) |
Kotlin
Class and methods must be open for AOP to work.
| Return Type | Example | |-------------|---------| | T / T? / Unit | fun getUser(id: String): User? | | suspend fun ... : T | suspend fun getUserAsync(id: String): User (requires kotlinx-coroutines-core) | | Flow | fun getAllUsers(): Flow (requires kotlinx-coroutines-core) |
Common Pitfalls
| Problem | Solution | |---------|----------| | Annotations don't trigger | Java: class must be non-final. Kotlin: class and methods must be open | | Circuit breaker never opens | Check minimumRequiredCalls — need enough calls to evaluate | | Circuit breaker reacts to 404 | Implement CircuitBreakerPredicate to exclude business errors | | Fallback not called | Check method signature: return type compatible, parameters match subset | | Retry makes latency worse | Estimate worst-case: attempts × (delay + delayStep). Reduce for latency-sensitive paths | | Config not applied | Config key must match annotation value: @Retry("custom") → resilient.retry."custom" |
Troubleshooting
Verify AOP is working
# Check generated proxy classes
find build -name "*__AopProxy.java" | head -5
If no proxies are generated:
- Check the class is non-final (Java) /
open(Kotlin), and the method isopenin Kotlin. - Verify the annotation processor is wired: Java
annotationProcessor "ru.tinkoff.kora:annotation-processors", Kotlinksp "ru.tinkoff.kora:symbol-processors". - Clean rebuild:
./gradlew clean build --no-daemon
Enable debug logging
logging.levels {
"ru.tinkoff.kora.resilient": "DEBUG"
}
Assets
Templates in assets/:
| Template | Description | |----------|-------------| | ResilientService.java.template | Full resilience stack (Java) | | ResilientService.kt.template | Full resilience stack (Kotlin) | | RetryService.*.template | @Retry pattern | | CircuitBreakerService.*.template | @CircuitBreaker pattern | | TimeoutService.*.template | @Timeout pattern | | FallbackService.*.template | @Fallback pattern |
See [assets/README.md](assets/README.md) for usage.
See Also
- [kora-http-client](../kora-http-client/SKILL.md) — Pair resilient with outbound HTTP clients
- [kora-telemetry-metrics](../kora-telemetry-metrics/SKILL.md) — Monitor retry attempts, circuit breaker state
- [kora-aop-logging](../kora-aop-logging/SKILL.md) — Add logging to resilient services
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: kora-projects
- Source: kora-projects/kora-skills
- License: Apache-2.0
- Homepage: http://kora-projects.github.io/kora-docs
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.