From 92f71a48f2ed24236f407eaf6cc6f88cbd4173ce Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Mon, 18 Nov 2019 09:26:09 +0100 Subject: [PATCH] Scheduler - do not use interceptor to activate request context per exec - otherwise the scheduled bean must be proxyable --- .../deployment/SchedulerProcessor.java | 20 +++++--------- .../runtime/AbstractScheduledInvoker.java | 26 +++++++++++++++++++ .../scheduler/runtime/ScheduledInvoker.java | 2 +- 3 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/AbstractScheduledInvoker.java diff --git a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java index c85b1326a9f15..5777e40308cf2 100644 --- a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java +++ b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java @@ -61,7 +61,7 @@ import io.quarkus.gizmo.ResultHandle; import io.quarkus.scheduler.Scheduled; import io.quarkus.scheduler.ScheduledExecution; -import io.quarkus.scheduler.runtime.ScheduledInvoker; +import io.quarkus.scheduler.runtime.AbstractScheduledInvoker; import io.quarkus.scheduler.runtime.ScheduledMethodMetadata; import io.quarkus.scheduler.runtime.SchedulerConfig; import io.quarkus.scheduler.runtime.SchedulerRecorder; @@ -98,27 +98,19 @@ AnnotationsTransformerBuildItem annotationTransformer() { @Override public boolean appliesTo(org.jboss.jandex.AnnotationTarget.Kind kind) { - return kind == org.jboss.jandex.AnnotationTarget.Kind.CLASS - || kind == org.jboss.jandex.AnnotationTarget.Kind.METHOD; + return kind == org.jboss.jandex.AnnotationTarget.Kind.CLASS; } @Override public void transform(TransformationContext context) { - if (context.isClass() && context.getAnnotations().isEmpty()) { - // Class with no annotations but with @Scheduled method + if (context.isClass() && !BuiltinScope.isDeclaredOn(context.getTarget().asClass())) { + // Class with no built-in scope annotation but with @Scheduled method if (context.getTarget().asClass().annotations().containsKey(SCHEDULED_NAME) || context.getTarget().asClass().annotations().containsKey(SCHEDULES_NAME)) { LOGGER.debugf("Found scheduled business methods on a class %s with no annotations - adding @Singleton", context.getTarget()); context.transform().add(Singleton.class).done(); } - } else if (context.isMethod()) { - MethodInfo method = context.getTarget().asMethod(); - if ((method.hasAnnotation(SCHEDULED_NAME) || method.hasAnnotation(SCHEDULES_NAME)) - && !method.hasAnnotation(DotNames.ACTIVATE_REQUEST_CONTEXT)) { - // Activate request context during a scheduled method invocation - context.transform().add(DotNames.ACTIVATE_REQUEST_CONTEXT).done(); - } } } }); @@ -263,10 +255,10 @@ private String generateInvoker(BeanInfo bean, MethodInfo method, ClassOutput cla + HashUtil.sha1(sigBuilder.toString()); ClassCreator invokerCreator = ClassCreator.builder().classOutput(classOutput).className(generatedName) - .interfaces(ScheduledInvoker.class) + .superClass(AbstractScheduledInvoker.class) .build(); - MethodCreator invoke = invokerCreator.getMethodCreator("invoke", void.class, ScheduledExecution.class); + MethodCreator invoke = invokerCreator.getMethodCreator("invokeBean", void.class, ScheduledExecution.class); // InjectableBean handle = Arc.container().instance(bean); // handle.get().ping(); diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/AbstractScheduledInvoker.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/AbstractScheduledInvoker.java new file mode 100644 index 0000000000000..88b9fca3f8dcc --- /dev/null +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/AbstractScheduledInvoker.java @@ -0,0 +1,26 @@ +package io.quarkus.scheduler.runtime; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.ManagedContext; +import io.quarkus.scheduler.ScheduledExecution; + +public abstract class AbstractScheduledInvoker implements ScheduledInvoker { + + @Override + public void invoke(ScheduledExecution execution) { + ManagedContext requestContext = Arc.container().requestContext(); + if (requestContext.isActive()) { + invokeBean(execution); + } else { + try { + requestContext.activate(); + invokeBean(execution); + } finally { + requestContext.terminate(); + } + } + } + + public abstract void invokeBean(ScheduledExecution action); + +} diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledInvoker.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledInvoker.java index dede920a5f08f..c0519edbfa7bc 100644 --- a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledInvoker.java +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledInvoker.java @@ -9,6 +9,6 @@ */ public interface ScheduledInvoker { - void invoke(ScheduledExecution action); + void invoke(ScheduledExecution execution); }