Skip to content

Commit

Permalink
Quartz - Use the same dep. bean instance for both, execution and inte…
Browse files Browse the repository at this point in the history
…rruption of CdiAwareJob
  • Loading branch information
manovotn committed Jul 30, 2024
1 parent f2ea2b0 commit 2498f5c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

Expand Down Expand Up @@ -40,6 +41,7 @@ public class InterruptableJobTest {

static final CountDownLatch INTERRUPT_LATCH = new CountDownLatch(1);
static final CountDownLatch EXECUTE_LATCH = new CountDownLatch(1);
static Integer initCounter = 0;

static final CountDownLatch NON_INTERRUPTABLE_EXECUTE_LATCH = new CountDownLatch(1);
static final CountDownLatch NON_INTERRUPTABLE_HOLD_LATCH = new CountDownLatch(1);
Expand All @@ -66,7 +68,9 @@ public void testInterruptableJob() throws InterruptedException {
throw new RuntimeException(e);
}

assertTrue(INTERRUPT_LATCH.await(5, TimeUnit.SECONDS));
assertTrue(INTERRUPT_LATCH.await(3, TimeUnit.SECONDS));
// asserts that a single dep. scoped bean instance was used for both, execute() and interrupt() methods
assertTrue(initCounter == 1);
}

@Test
Expand Down Expand Up @@ -102,6 +106,11 @@ public void testNonInterruptableJob() throws InterruptedException {
@ApplicationScoped
static class MyJob implements InterruptableJob {

@PostConstruct
public void postConstruct() {
initCounter++;
}

@Override
public void execute(JobExecutionContext context) {
EXECUTE_LATCH.countDown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@
*/
class CdiAwareJob implements InterruptableJob {

private final Instance<? extends Job> jobInstance;
private final Instance.Handle<? extends Job> handle;
private final Job beanInstance;

public CdiAwareJob(Instance<? extends Job> jobInstance) {
this.jobInstance = jobInstance;
public CdiAwareJob(Instance.Handle<? extends Job> handle) {
this.handle = handle;
this.beanInstance = handle.get();
}

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Instance.Handle<? extends Job> handle = jobInstance.getHandle();
boolean refire = false;
try {
handle.get().execute(context);
beanInstance.execute(context);
} catch (JobExecutionException e) {
refire = e.refireImmediately();
throw e;
Expand All @@ -43,16 +44,9 @@ public void execute(JobExecutionContext context) throws JobExecutionException {

@Override
public void interrupt() throws UnableToInterruptJobException {
Instance.Handle<? extends Job> handle = jobInstance.getHandle();
// delegate if possible; throw an exception in other cases
if (InterruptableJob.class.isAssignableFrom(handle.getBean().getBeanClass())) {
try {
((InterruptableJob) handle.get()).interrupt();
} finally {
if (handle.getBean().getScope().equals(Dependent.class)) {
handle.destroy();
}
}
((InterruptableJob) beanInstance).interrupt();
} else {
throw new UnableToInterruptJobException("Job " + handle.getBean().getBeanClass()
+ " can not be interrupted, since it does not implement " + InterruptableJob.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ public Job newJob(TriggerFiredBundle bundle, org.quartz.Scheduler Scheduler) thr
Instance<? extends Job> instance = jobs.select(jobClass);
if (instance.isResolvable()) {
// This is a job backed by a CDI bean
return jobWithSpanWrapper(new CdiAwareJob(instance));
return jobWithSpanWrapper(new CdiAwareJob(instance.getHandle()));
}
// Instantiate a plain job class
return jobWithSpanWrapper(super.newJob(bundle, Scheduler));
Expand Down

0 comments on commit 2498f5c

Please sign in to comment.