From e2cb609a2d2b3b1631251accb547273a865bb0df Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 27 Aug 2024 17:10:36 +0200 Subject: [PATCH 1/5] Try to cancel timer always, and only search if timer cancellation fails --- .../services/ejb/timer/EJBTimerScheduler.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java index 48f09f2c6f..250d757886 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java @@ -114,6 +114,7 @@ public void executeTimerJob(Timer timer) { try { executeTimerJobInstance(timerJobInstance); } catch (Exception e) { + logger.error("Error executing timer handle {}", timerJobInstance.getJobHandle(), e); recoverTimerJobInstance(timerJob, timer, e); } } @@ -139,7 +140,7 @@ else if (ejbTimerJob.getTimerJobInstance().getTrigger().hasNextFireTime() != nul // because of the transaction, so we need to do this here. tx = timerJobInstance -> { logger.warn("Execution of time failed Interval Trigger failed. Skipping {}", timerJobInstance); - if (removeJob(timerJobInstance.getJobHandle(), null)) { + if (removeJob(timerJobInstance.getJobHandle(), timer, true)) { internalSchedule(timerJobInstance); } else { logger.debug("Interval trigger {} was removed before rescheduling", timerJobInstance); @@ -246,7 +247,11 @@ private Serializable removeTransientFields(Serializable info) { return info; } - public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { + public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { + return removeJob(jobHandle, ejbTimer, false); + } + + public boolean removeJob(JobHandle jobHandle, Timer ejbTimer, boolean searchIfFailed) { EjbGlobalJobHandle ejbHandle = (EjbGlobalJobHandle) jobHandle; if (useLocalCache) { boolean removedFromCache = localCache.remove(ejbHandle.getUuid()) != null; @@ -257,9 +262,11 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { try { ejbTimer.cancel(); return true; - } catch (Throwable e) { - logger.debug("Timer cancel error due to {}", e.getMessage()); - return false; + } catch (Exception e) { + logger.warn("Timer cancel error for handle {}", ejbHandle, e); + if (!searchIfFailed) { + return false; + } } } @@ -271,7 +278,7 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { try { ((TimerHandle) ejbTimerHandle).getTimer().cancel(); } catch (Throwable e) { - logger.debug("Timer cancel error due to {}", e.getMessage()); + logger.warn("Timer cancel error for handle {}", ejbTimerHandle, e); return false; } return true; @@ -288,12 +295,12 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); if (handle.getUuid().equals(ejbHandle.getUuid())) { - logger.debug("Job handle {} does match timer and is going to be canceled", jobHandle); + logger.info("Job handle {} does match timer and is going to be canceled", jobHandle); try { timer.cancel(); } catch (Throwable e) { - logger.debug("Timer cancel error due to {}", e.getMessage()); + logger.warn("Timer cancel error for handle {}", handle, e); return false; } return true; @@ -303,7 +310,7 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { logger.debug("Timer {} has already expired or was canceled ", timer); } } - logger.debug("Job handle {} does not match any timer on {} scheduler service", jobHandle, this); + logger.info("Job handle {} does not match any timer on {} scheduler service", jobHandle, this); return false; } From fc488fb21f7121bb7e88394cc093436cdb662f6d Mon Sep 17 00:00:00 2001 From: krisv Date: Wed, 11 Sep 2024 13:34:16 +0200 Subject: [PATCH 2/5] Skipping list search completely if !searchIfFailed --- .../org/jbpm/services/ejb/timer/EJBTimerScheduler.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java index 250d757886..c5cc94c366 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java @@ -282,11 +282,18 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer, boolean searchIfFa return false; } return true; + } else { + logger.warn("No TimerHandle found for {}: {}", ejbHandle, ejbTimerHandle); } } else { logger.warn("No timerJobInstance available for {}", ejbHandle); } + if (!searchIfFailed) { + logger.warn("Timer not found for {} and {}, skipping list search", ejbHandle, ejbTimer); + return false; + } + for (Timer timer : timerService.getTimers()) { try { Serializable info = timer.getInfo(); From d79847f072b2d43b68d829478ba9f2c545b0f4ee Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 27 Sep 2024 15:34:53 +0200 Subject: [PATCH 3/5] [JBPM-10242] Always skipping linear search Unless explicilty stated with property org.jbpm.ejb.timer.linear.search --- .../services/ejb/timer/EJBTimerScheduler.java | 124 +++++++++--------- .../ejb/timer/EJBTimerSchedulerTest.java | 8 ++ 2 files changed, 70 insertions(+), 62 deletions(-) diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java index c5cc94c366..ab3fea23f4 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java @@ -140,7 +140,7 @@ else if (ejbTimerJob.getTimerJobInstance().getTrigger().hasNextFireTime() != nul // because of the transaction, so we need to do this here. tx = timerJobInstance -> { logger.warn("Execution of time failed Interval Trigger failed. Skipping {}", timerJobInstance); - if (removeJob(timerJobInstance.getJobHandle(), timer, true)) { + if (removeJob(timerJobInstance.getJobHandle(), timer)) { internalSchedule(timerJobInstance); } else { logger.debug("Interval trigger {} was removed before rescheduling", timerJobInstance); @@ -247,11 +247,12 @@ private Serializable removeTransientFields(Serializable info) { return info; } - public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { - return removeJob(jobHandle, ejbTimer, false); + private boolean performLinearSearch() { + return Boolean.getBoolean("org.jbpm.ejb.timer.linear.search"); } + - public boolean removeJob(JobHandle jobHandle, Timer ejbTimer, boolean searchIfFailed) { + public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { EjbGlobalJobHandle ejbHandle = (EjbGlobalJobHandle) jobHandle; if (useLocalCache) { boolean removedFromCache = localCache.remove(ejbHandle.getUuid()) != null; @@ -263,10 +264,8 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer, boolean searchIfFa ejbTimer.cancel(); return true; } catch (Exception e) { - logger.warn("Timer cancel error for handle {}", ejbHandle, e); - if (!searchIfFailed) { - return false; - } + logger.warn("Timer cancel error for handle {}", ejbHandle.getUuid(), e); + return false; } } @@ -289,36 +288,36 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer, boolean searchIfFa logger.warn("No timerJobInstance available for {}", ejbHandle); } - if (!searchIfFailed) { - logger.warn("Timer not found for {} and {}, skipping list search", ejbHandle, ejbTimer); + if (performLinearSearch()) { + for (Timer timer : timerService.getTimers()) { + try { + Serializable info = timer.getInfo(); + if (info instanceof EjbTimerJob) { + EjbTimerJob job = (EjbTimerJob) info; + + EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); + if (handle.getUuid().equals(ejbHandle.getUuid())) { + logger.info("Job handle {} does match timer and is going to be canceled", jobHandle); + + try { + timer.cancel(); + } catch (Throwable e) { + logger.warn("Timer cancel error for handle {}", handle, e); + return false; + } + return true; + } + } + } catch (NoSuchObjectLocalException e) { + logger.debug("Timer {} has already expired or was canceled ", timer); + } + } + logger.info("Job handle {} does not match any timer on {} scheduler service", jobHandle, this); + return false; + } else { + logger.warn("Skipping linear search to delete uuid {}", ejbHandle.getUuid()); return false; } - - for (Timer timer : timerService.getTimers()) { - try { - Serializable info = timer.getInfo(); - if (info instanceof EjbTimerJob) { - EjbTimerJob job = (EjbTimerJob) info; - - EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); - if (handle.getUuid().equals(ejbHandle.getUuid())) { - logger.info("Job handle {} does match timer and is going to be canceled", jobHandle); - - try { - timer.cancel(); - } catch (Throwable e) { - logger.warn("Timer cancel error for handle {}", handle, e); - return false; - } - return true; - } - } - } catch (NoSuchObjectLocalException e) { - logger.debug("Timer {} has already expired or was canceled ", timer); - } - } - logger.info("Job handle {} does not match any timer on {} scheduler service", jobHandle, this); - return false; } @@ -330,33 +329,34 @@ public TimerJobInstance getTimerByName(String jobName) { return localCache.get(jobName); } } - TimerJobInstance found = null; - - for (Timer timer : timerService.getTimers()) { - try { - Serializable info = timer.getInfo(); - if (info instanceof EjbTimerJob) { - EjbTimerJob job = (EjbTimerJob) info; - - EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); - - if (handle.getUuid().equals(jobName)) { - found = handle.getTimerJobInstance(); - if (useLocalCache) { - localCache.putIfAbsent(jobName, found); - } - logger.debug("Job {} does match timer and is going to be returned {}", jobName, found); - - break; - } - } - } catch (NoSuchObjectLocalException e) { - logger.debug("Timer info for {} was not found ", timer); + TimerJobInstance found = null; + if (performLinearSearch()) { + for (Timer timer : timerService.getTimers()) { + try { + Serializable info = timer.getInfo(); + if (info instanceof EjbTimerJob) { + EjbTimerJob job = (EjbTimerJob) info; + + EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); + + if (handle.getUuid().equals(jobName)) { + found = handle.getTimerJobInstance(); + if (useLocalCache) { + localCache.putIfAbsent(jobName, found); + } + logger.debug("Job {} does match timer and is going to be returned {}", jobName, found); + break; + } + } + } catch (NoSuchObjectLocalException e) { + logger.debug("Timer info for {} was not found ", timer); + } } - } - - return found; - } + } else { + logger.warn("Skipping linear search to find uuid {}", jobName); + } + return found; + } public void evictCache(JobHandle jobHandle) { String jobName = ((EjbGlobalJobHandle) jobHandle).getUuid(); diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java index 8356362503..c470532b4e 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java @@ -28,6 +28,7 @@ import org.drools.core.time.impl.TimerJobInstance; import org.jbpm.persistence.timer.GlobalJpaTimerJobInstance; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -41,6 +42,8 @@ public class EJBTimerSchedulerTest { @Before public void setup() { + + System.setProperty("org.jbpm.ejb.timer.linear.search", "true"); TimerService timerService = mock(TimerService.class); when(timerService.getTimers()).thenReturn(timers); @@ -58,6 +61,11 @@ public void setup() { scheduler.timerService = timerService; } + @After + public void cleanup() { + System.clearProperty("org.jbpm.ejb.timer.linear.search"); + } + @Test public void testEjbTimerSchedulerTestOnTimerLoop() { // first call to go over list of timers should not add anything to the cache as there is no matching timers From 22f29fc25f69e9c7b5c2e3eec0b52e15b8f2c48e Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Tue, 1 Oct 2024 12:28:21 +0200 Subject: [PATCH 4/5] [JBPM-10242] Disable linear search on condition Setting org.jbpm.ejb.timer.disable.linear.search and org.jbpm.ejb.timer.disable.linear.remove to true --- .../services/ejb/timer/EJBTimerScheduler.java | 125 +++++++----------- .../ejb/timer/EJBTimerSchedulerTest.java | 8 -- 2 files changed, 50 insertions(+), 83 deletions(-) diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java index ab3fea23f4..93ebb6b546 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java @@ -26,9 +26,13 @@ import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.Date; +import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; import javax.annotation.PostConstruct; import javax.annotation.Resource; @@ -247,8 +251,8 @@ private Serializable removeTransientFields(Serializable info) { return info; } - private boolean performLinearSearch() { - return Boolean.getBoolean("org.jbpm.ejb.timer.linear.search"); + private boolean disableLinearSearch(String suffix) { + return Boolean.getBoolean("org.jbpm.ejb.timer.disable.linear." + suffix); } @@ -256,106 +260,77 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { EjbGlobalJobHandle ejbHandle = (EjbGlobalJobHandle) jobHandle; if (useLocalCache) { boolean removedFromCache = localCache.remove(ejbHandle.getUuid()) != null; - logger.debug("Job handle {} is {} removed from cache ", jobHandle, removedFromCache ? "" : "not" ); + logger.debug("Job handle {} is {} removed from cache ", jobHandle, removedFromCache ? "" : "not"); } if (ejbTimer != null) { - try { - ejbTimer.cancel(); - return true; - } catch (Exception e) { - logger.warn("Timer cancel error for handle {}", ejbHandle.getUuid(), e); - return false; - } + return cancelTimer(ejbTimer, ejbHandle); } // small speed improvement using the ejb serializable info handler GlobalJpaTimerJobInstance timerJobInstance = (GlobalJpaTimerJobInstance) ejbHandle.getTimerJobInstance(); if (timerJobInstance != null) { - Object ejbTimerHandle = timerJobInstance.getTimerInfo(); - if(ejbTimerHandle instanceof TimerHandle) { - try { - ((TimerHandle) ejbTimerHandle).getTimer().cancel(); - } catch (Throwable e) { - logger.warn("Timer cancel error for handle {}", ejbTimerHandle, e); - return false; - } - return true; - } else { - logger.warn("No TimerHandle found for {}: {}", ejbHandle, ejbTimerHandle); + Object ejbTimerHandle = timerJobInstance.getTimerInfo(); + if (ejbTimerHandle instanceof TimerHandle) { + return cancelTimer(((TimerHandle) ejbTimerHandle).getTimer(), ejbHandle); } - } else { - logger.warn("No timerJobInstance available for {}", ejbHandle); } + logger.debug("No valid TimerJob instance {} available for Job handle {}", timerJobInstance, ejbHandle); + return linearSearch("remove", ejbHandle.getUuid(), + (timer, job) -> cancelTimer(timer, (EjbGlobalJobHandle) job.getJobHandle())).orElse(false); + } - if (performLinearSearch()) { - for (Timer timer : timerService.getTimers()) { - try { - Serializable info = timer.getInfo(); - if (info instanceof EjbTimerJob) { - EjbTimerJob job = (EjbTimerJob) info; - - EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); - if (handle.getUuid().equals(ejbHandle.getUuid())) { - logger.info("Job handle {} does match timer and is going to be canceled", jobHandle); - - try { - timer.cancel(); - } catch (Throwable e) { - logger.warn("Timer cancel error for handle {}", handle, e); - return false; - } - return true; - } - } - } catch (NoSuchObjectLocalException e) { - logger.debug("Timer {} has already expired or was canceled ", timer); - } + public TimerJobInstance getTimerByName(String jobName) { + if (useLocalCache) { + TimerJobInstance found = localCache.get(jobName); + if (found != null) { + logger.debug("Timer {} found in cache", jobName); + return found; } - logger.info("Job handle {} does not match any timer on {} scheduler service", jobHandle, this); - return false; - } else { - logger.warn("Skipping linear search to delete uuid {}", ejbHandle.getUuid()); - return false; + logger.debug("Timer {} not found in cache", jobName); } - } - + return linearSearch("search", jobName, (timer, job) -> { + if (useLocalCache) { + localCache.putIfAbsent(jobName, job); + } + return job; + }).orElse(null); + } + private boolean cancelTimer(Timer timer, EjbGlobalJobHandle ejbHandle) { + try { + timer.cancel(); + return true; + } catch (Exception ex) { + logger.warn("Cancelling timer failed for handle {}", ejbHandle, ex); + return false; + } + } - public TimerJobInstance getTimerByName(String jobName) { - if (useLocalCache) { - if (localCache.containsKey(jobName)) { - logger.debug("Found job {} in cache returning", jobName); - return localCache.get(jobName); - } - } - TimerJobInstance found = null; - if (performLinearSearch()) { + private Optional linearSearch(String suffix, String uuid, BiFunction function) { + if (disableLinearSearch(suffix)) { + logger.warn("Skipping linear search to {} UUID {}", suffix, uuid); + } else { + logger.info("Searching UUID {} on {} scheduler service", uuid, this); for (Timer timer : timerService.getTimers()) { try { Serializable info = timer.getInfo(); if (info instanceof EjbTimerJob) { EjbTimerJob job = (EjbTimerJob) info; - EjbGlobalJobHandle handle = (EjbGlobalJobHandle) job.getTimerJobInstance().getJobHandle(); - - if (handle.getUuid().equals(jobName)) { - found = handle.getTimerJobInstance(); - if (useLocalCache) { - localCache.putIfAbsent(jobName, found); - } - logger.debug("Job {} does match timer and is going to be returned {}", jobName, found); - break; + if (handle.getUuid().equals(uuid)) { + logger.debug("UIID {} does match timer {} and handle {}", uuid, timer, + job.getTimerJobInstance()); + return Optional.of(function.apply(timer, job.getTimerJobInstance())); } } } catch (NoSuchObjectLocalException e) { - logger.debug("Timer info for {} was not found ", timer); + logger.info("Info for timer {} is not there ", timer, e); } } - } else { - logger.warn("Skipping linear search to find uuid {}", jobName); + logger.info("UUID {} does not match any timer on {} scheduler service", uuid, this); } - return found; + return Optional.empty(); } public void evictCache(JobHandle jobHandle) { diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java index c470532b4e..8356362503 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/test/java/org/jbpm/services/ejb/timer/EJBTimerSchedulerTest.java @@ -28,7 +28,6 @@ import org.drools.core.time.impl.TimerJobInstance; import org.jbpm.persistence.timer.GlobalJpaTimerJobInstance; -import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -42,8 +41,6 @@ public class EJBTimerSchedulerTest { @Before public void setup() { - - System.setProperty("org.jbpm.ejb.timer.linear.search", "true"); TimerService timerService = mock(TimerService.class); when(timerService.getTimers()).thenReturn(timers); @@ -61,11 +58,6 @@ public void setup() { scheduler.timerService = timerService; } - @After - public void cleanup() { - System.clearProperty("org.jbpm.ejb.timer.linear.search"); - } - @Test public void testEjbTimerSchedulerTestOnTimerLoop() { // first call to go over list of timers should not add anything to the cache as there is no matching timers From 7007fdbcc517fa4204ea8c1bce68329193fcc89b Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Wed, 2 Oct 2024 12:51:11 +0200 Subject: [PATCH 5/5] [JBPM-10242] Fixing integration tests --- .../services/ejb/timer/EJBTimerScheduler.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java index 93ebb6b546..7a9b44a35f 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EJBTimerScheduler.java @@ -272,7 +272,13 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) { if (timerJobInstance != null) { Object ejbTimerHandle = timerJobInstance.getTimerInfo(); if (ejbTimerHandle instanceof TimerHandle) { - return cancelTimer(((TimerHandle) ejbTimerHandle).getTimer(), ejbHandle); + try { + ((TimerHandle) ejbTimerHandle).getTimer().cancel(); + return true; + } catch (Exception ex) { + logger.warn("Cancelling timer failed for handle {}", ejbHandle, ex); + return false; + } } } logger.debug("No valid TimerJob instance {} available for Job handle {}", timerJobInstance, ejbHandle); @@ -284,19 +290,20 @@ public TimerJobInstance getTimerByName(String jobName) { if (useLocalCache) { TimerJobInstance found = localCache.get(jobName); if (found != null) { - logger.debug("Timer {} found in cache", jobName); + logger.debug("Found timer job instance with name {} in cache, returning {}", jobName, found); return found; } - logger.debug("Timer {} not found in cache", jobName); + logger.debug("Timer Job Instance with name {} not found in cache", jobName); } return linearSearch("search", jobName, (timer, job) -> { - if (useLocalCache) { + if (useLocalCache && job != null) { localCache.putIfAbsent(jobName, job); } return job; }).orElse(null); } + private boolean cancelTimer(Timer timer, EjbGlobalJobHandle ejbHandle) { try { timer.cancel(); @@ -321,7 +328,7 @@ private Optional linearSearch(String suffix, String uuid, BiFunction