Skip to content

Commit

Permalink
SmallRye Fault Tolerance: few tiny improvements of FT scanner
Browse files Browse the repository at this point in the history
With this commit, we'll no longer create `DotName`s for annotations, because
we already have them pre-created in the `DotNames` class.

Also, this commit replaces a stream with a simple `for` loop in a relatively
hot method.
  • Loading branch information
Ladicek committed Jan 13, 2025
1 parent f3c54ef commit 7e20944
Showing 1 changed file with 51 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,45 @@ FaultToleranceMethod createFaultToleranceMethod(ClassInfo beanClass, MethodInfo
result.beanClass = getClassProxy(beanClass);
result.method = createMethodDescriptor(method);

result.applyFaultTolerance = getAnnotation(ApplyFaultTolerance.class, method, beanClass, annotationsPresentDirectly);
result.applyGuard = getAnnotation(ApplyGuard.class, method, beanClass, annotationsPresentDirectly);

result.asynchronous = getAnnotation(Asynchronous.class, method, beanClass, annotationsPresentDirectly);
result.asynchronousNonBlocking = getAnnotation(AsynchronousNonBlocking.class, method, beanClass,
annotationsPresentDirectly);
result.blocking = getAnnotation(Blocking.class, method, beanClass, annotationsPresentDirectly);
result.nonBlocking = getAnnotation(NonBlocking.class, method, beanClass, annotationsPresentDirectly);

result.bulkhead = getAnnotation(Bulkhead.class, method, beanClass, annotationsPresentDirectly);
result.circuitBreaker = getAnnotation(CircuitBreaker.class, method, beanClass, annotationsPresentDirectly);
result.circuitBreakerName = getAnnotation(CircuitBreakerName.class, method, beanClass, annotationsPresentDirectly);
result.fallback = getAnnotation(Fallback.class, method, beanClass, annotationsPresentDirectly);
result.rateLimit = getAnnotation(RateLimit.class, method, beanClass, annotationsPresentDirectly);
result.retry = getAnnotation(Retry.class, method, beanClass, annotationsPresentDirectly);
result.timeout = getAnnotation(Timeout.class, method, beanClass, annotationsPresentDirectly);

result.customBackoff = getAnnotation(CustomBackoff.class, method, beanClass, annotationsPresentDirectly);
result.exponentialBackoff = getAnnotation(ExponentialBackoff.class, method, beanClass, annotationsPresentDirectly);
result.fibonacciBackoff = getAnnotation(FibonacciBackoff.class, method, beanClass, annotationsPresentDirectly);
result.retryWhen = getAnnotation(RetryWhen.class, method, beanClass, annotationsPresentDirectly);
result.beforeRetry = getAnnotation(BeforeRetry.class, method, beanClass, annotationsPresentDirectly);
result.applyFaultTolerance = getAnnotation(ApplyFaultTolerance.class, DotNames.APPLY_FAULT_TOLERANCE,
method, beanClass, annotationsPresentDirectly);
result.applyGuard = getAnnotation(ApplyGuard.class, DotNames.APPLY_GUARD,
method, beanClass, annotationsPresentDirectly);

result.asynchronous = getAnnotation(Asynchronous.class, DotNames.ASYNCHRONOUS,
method, beanClass, annotationsPresentDirectly);
result.asynchronousNonBlocking = getAnnotation(AsynchronousNonBlocking.class, DotNames.ASYNCHRONOUS_NON_BLOCKING,
method, beanClass, annotationsPresentDirectly);
result.blocking = getAnnotation(Blocking.class, DotNames.BLOCKING,
method, beanClass, annotationsPresentDirectly);
result.nonBlocking = getAnnotation(NonBlocking.class, DotNames.NON_BLOCKING,
method, beanClass, annotationsPresentDirectly);

result.bulkhead = getAnnotation(Bulkhead.class, DotNames.BULKHEAD,
method, beanClass, annotationsPresentDirectly);
result.circuitBreaker = getAnnotation(CircuitBreaker.class, DotNames.CIRCUIT_BREAKER,
method, beanClass, annotationsPresentDirectly);
result.circuitBreakerName = getAnnotation(CircuitBreakerName.class, DotNames.CIRCUIT_BREAKER_NAME,
method, beanClass, annotationsPresentDirectly);
result.fallback = getAnnotation(Fallback.class, DotNames.FALLBACK,
method, beanClass, annotationsPresentDirectly);
result.rateLimit = getAnnotation(RateLimit.class, DotNames.RATE_LIMIT,
method, beanClass, annotationsPresentDirectly);
result.retry = getAnnotation(Retry.class, DotNames.RETRY,
method, beanClass, annotationsPresentDirectly);
result.timeout = getAnnotation(Timeout.class, DotNames.TIMEOUT,
method, beanClass, annotationsPresentDirectly);

result.customBackoff = getAnnotation(CustomBackoff.class, DotNames.CUSTOM_BACKOFF,
method, beanClass, annotationsPresentDirectly);
result.exponentialBackoff = getAnnotation(ExponentialBackoff.class, DotNames.EXPONENTIAL_BACKOFF,
method, beanClass, annotationsPresentDirectly);
result.fibonacciBackoff = getAnnotation(FibonacciBackoff.class, DotNames.FIBONACCI_BACKOFF,
method, beanClass, annotationsPresentDirectly);
result.retryWhen = getAnnotation(RetryWhen.class, DotNames.RETRY_WHEN,
method, beanClass, annotationsPresentDirectly);
result.beforeRetry = getAnnotation(BeforeRetry.class, DotNames.BEFORE_RETRY,
method, beanClass, annotationsPresentDirectly);

result.annotationsPresentDirectly = annotationsPresentDirectly;

Expand All @@ -164,25 +181,25 @@ private MethodDescriptor createMethodDescriptor(MethodInfo method) {
MethodDescriptor result = new MethodDescriptor();
result.declaringClass = getClassProxy(method.declaringClass());
result.name = method.name();
result.parameterTypes = method.parameterTypes()
.stream()
.map(this::getClassProxy)
.toArray(Class[]::new);
Class<?>[] parameterTypes = new Class<?>[method.parametersCount()];
for (int i = 0; i < method.parametersCount(); i++) {
parameterTypes[i] = getClassProxy(method.parameterType(i));
}
result.parameterTypes = parameterTypes;
result.returnType = getClassProxy(method.returnType());
return result;
}

private <A extends Annotation> A getAnnotation(Class<A> annotationType, MethodInfo method,
ClassInfo beanClass, Set<Class<? extends Annotation>> directlyPresent) {
private <A extends Annotation> A getAnnotation(Class<A> annotationType, DotName annotationName,
MethodInfo method, ClassInfo beanClass, Set<Class<? extends Annotation>> directlyPresent) {

DotName annotationName = DotName.createSimple(annotationType);
if (annotationStore.hasAnnotation(method, annotationName)) {
directlyPresent.add(annotationType);
AnnotationInstance annotation = annotationStore.getAnnotation(method, annotationName);
return createAnnotation(annotationType, annotation);
}

return getAnnotationFromClass(annotationType, beanClass);
return getAnnotationFromClass(annotationType, annotationName, beanClass);
}

// ---
Expand Down Expand Up @@ -283,8 +300,9 @@ private List<MethodDescriptor> createMethodDescriptorsIfNotEmpty(Collection<Meth

// ---

private <A extends Annotation> A getAnnotationFromClass(Class<A> annotationType, ClassInfo clazz) {
DotName annotationName = DotName.createSimple(annotationType);
// almost all FT annotations are inherited (except `@Blocking` and `@NonBlocking`, which we'll remove soon,
// and `@CircuitBreakerName`, which can only be put on methods), so no need to test for that here
private <A extends Annotation> A getAnnotationFromClass(Class<A> annotationType, DotName annotationName, ClassInfo clazz) {
if (annotationStore.hasAnnotation(clazz, annotationName)) {
AnnotationInstance annotation = annotationStore.getAnnotation(clazz, annotationName);
return createAnnotation(annotationType, annotation);
Expand All @@ -299,7 +317,7 @@ private <A extends Annotation> A getAnnotationFromClass(Class<A> annotationType,
if (parentClass == null) {
return null;
}
return getAnnotationFromClass(annotationType, parentClass);
return getAnnotationFromClass(annotationType, annotationName, parentClass);
}

private <A extends Annotation> A createAnnotation(Class<A> annotationType, AnnotationInstance instance) {
Expand Down

0 comments on commit 7e20944

Please sign in to comment.