Skip to content

Commit

Permalink
[JBPM-10242] Disable linear search on condition
Browse files Browse the repository at this point in the history
Setting org.jbpm.ejb.timer.disable.linear.search and
org.jbpm.ejb.timer.disable.linear.remove to true
  • Loading branch information
fjtirado committed Oct 1, 2024
1 parent d79847f commit 77f5bdd
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,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);
}


Expand All @@ -260,67 +260,51 @@ public boolean removeJob(JobHandle jobHandle, Timer ejbTimer) {
}

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);
return cancelTimer(((TimerHandle) ejbTimerHandle).getTimer(), ejbTimerHandle);
}
} else {
logger.warn("No timerJobInstance available for {}", ejbHandle);
}
logger.info("No valid TimerJob instance {} available for Job handle {}", timerJobInstance, ejbHandle);

if (performLinearSearch()) {
if (disableLinearSearch("remove")) {
logger.warn("Skipping linear search to delete uuid {}", ejbHandle.getUuid());
} else {
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;
logger.debug("Job handle {} does match timer and is going to be canceled", jobHandle);
return cancelTimer(timer, ejbHandle);
}
}
} catch (NoSuchObjectLocalException e) {
logger.debug("Timer {} has already expired or was canceled ", timer);
logger.info("Timer info for {} is not there", timer, e);
}
}
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.info("UUID {} does not match any timer on {} scheduler service", ejbHandle.getUuid(), this);
}
}

return false;
}

private boolean cancelTimer(Timer timer, Object ejbTimerHandle) {
try {
timer.cancel();
return true;
} catch (Exception ex) {
logger.warn("Timer cancel failed for handle {}", ejbTimerHandle, ex);
return false;
}
}

public TimerJobInstance getTimerByName(String jobName) {
if (useLocalCache) {
Expand All @@ -329,33 +313,32 @@ public TimerJobInstance getTimerByName(String jobName) {
return localCache.get(jobName);
}
}
TimerJobInstance found = null;
if (performLinearSearch()) {
if (disableLinearSearch("search")) {
logger.warn("Skipping linear search to find uuid {}", jobName);
} else {
logger.info("Searching uuid {} in the entire timer db", jobName);
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();
TimerJobInstance found = handle.getTimerJobInstance();
if (useLocalCache) {
localCache.putIfAbsent(jobName, found);
}
logger.debug("Job {} does match timer and is going to be returned {}", jobName, found);
break;
return found;
}
}
} catch (NoSuchObjectLocalException e) {
logger.debug("Timer info for {} was not found ", timer);
logger.info("Timer info for {} 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", jobName, this);
}
return found;
return null;
}

public void evictCache(JobHandle jobHandle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);

Expand All @@ -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
Expand Down

0 comments on commit 77f5bdd

Please sign in to comment.