diff --git a/jbpm-services/jbpm-executor/src/main/java/org/jbpm/executor/impl/AbstractAvailableJobsExecutor.java b/jbpm-services/jbpm-executor/src/main/java/org/jbpm/executor/impl/AbstractAvailableJobsExecutor.java index 18253c947e..415f4ba004 100644 --- a/jbpm-services/jbpm-executor/src/main/java/org/jbpm/executor/impl/AbstractAvailableJobsExecutor.java +++ b/jbpm-services/jbpm-executor/src/main/java/org/jbpm/executor/impl/AbstractAvailableJobsExecutor.java @@ -132,7 +132,9 @@ public void executeGivenJob(RequestInfo request) { ctx.setData("ClassLoader", cl); // add scheduled execution time - ctx.setData("scheduledExecutionTime", request.getTime()); + if(ctx.getData("scheduledExecutionTime") == null) { + ctx.setData("scheduledExecutionTime", request.getTime()); + } cmd = classCacheManager.findCommand(request.getCommandName(), cl); // increment execution counter directly to cover both success and failure paths diff --git a/jbpm-services/jbpm-executor/src/test/java/org/jbpm/executor/LogCleanupCommandTest.java b/jbpm-services/jbpm-executor/src/test/java/org/jbpm/executor/LogCleanupCommandTest.java index ae0279090c..9690a897c5 100644 --- a/jbpm-services/jbpm-executor/src/test/java/org/jbpm/executor/LogCleanupCommandTest.java +++ b/jbpm-services/jbpm-executor/src/test/java/org/jbpm/executor/LogCleanupCommandTest.java @@ -222,4 +222,52 @@ public void logCleanupNextRunFixedIntervalTooSmallTest() throws InterruptedExcep assertTrue(diff >= 2000 && diff < 3000); System.clearProperty("byteman.jpaaudit.sleep"); } + + @Test(timeout=10000) + @BMScript(value = "byteman-scripts/simulateSlowLogCleanupCommand.btm") + public void logCleanupNextRunFixedPaginationTest() throws InterruptedException { + CountDownAsyncJobListener countDownListener = configureListener(1); + // this delay will be invoked 3 times during the test, resulting in an overall delay of 2s + System.setProperty("byteman.jpaaudit.sleep", "666"); + // number of records to be returned by JPAAuditLogService.doDelete + System.setProperty("byteman.jpaaudit.delete", "1000"); + + CommandContext ctxCMD = new CommandContext(); + ctxCMD.setData("businessKey", UUID.randomUUID().toString()); + ctxCMD.setData("NextRun", "10s"); + ctxCMD.setData("EmfName", "org.jbpm.executor"); + ctxCMD.setData("SkipProcessLog", "true"); + ctxCMD.setData("SkipTaskLog", "true"); + ctxCMD.setData("RepeatMode", "fixed"); + ctxCMD.setData("RecordsPerTransaction", 500); + executorService.scheduleRequest("org.jbpm.executor.commands.LogCleanupCommand", ctxCMD); + + // waiting until the first LogCleanupCommand execution is done + countDownListener.waitTillCompleted(); + System.clearProperty("byteman.jpaaudit.delete"); + // as the number of records to be deleted > RecordsPerTransaction, a second LogCleanupCommand will be scheduled for immediate execution + countDownListener.reset(1); + countDownListener.waitTillCompleted(); + + List rescheduled = executorService.getRequestsByBusinessKey((String)ctxCMD.getData("businessKey"), Arrays.asList(STATUS.QUEUED), new QueryContext()); + // check if the job has been rescheduled + assertEquals(1, rescheduled.size()); + + List inErrorRequests = executorService.getInErrorRequests(new QueryContext()); + assertEquals(0, inErrorRequests.size()); + List queuedRequests = executorService.getQueuedRequests(new QueryContext()); + assertEquals(1, queuedRequests.size()); + List executedRequests = executorService.getCompletedRequests(new QueryContext()); + assertEquals(2, executedRequests.size()); + + executorService.cancelRequest(queuedRequests.get(0).getId()); + + long firstExecution = executedRequests.get(0).getTime().getTime(); + long lastExecution = queuedRequests.get(queuedRequests.size()-1).getTime().getTime(); + + // time difference between first and last should be around 10 seconds, even if the original command got split into two executions due to RecordsPerTransaction + long diff = lastExecution - firstExecution; + assertTrue(diff < 11000); + System.clearProperty("byteman.jpaaudit.sleep"); + } } diff --git a/jbpm-services/jbpm-executor/src/test/resources/byteman-scripts/simulateSlowLogCleanupCommand.btm b/jbpm-services/jbpm-executor/src/test/resources/byteman-scripts/simulateSlowLogCleanupCommand.btm index a4d52c2b7e..152de1a7c1 100644 --- a/jbpm-services/jbpm-executor/src/test/resources/byteman-scripts/simulateSlowLogCleanupCommand.btm +++ b/jbpm-services/jbpm-executor/src/test/resources/byteman-scripts/simulateSlowLogCleanupCommand.btm @@ -10,6 +10,20 @@ AT ENTRY IF TRUE DO debug("Pausing JPAAuditLogService.doDelete for " + Integer.getInteger("byteman.jpaaudit.sleep", 500) + "ms"); Thread.sleep(Integer.getInteger("byteman.jpaaudit.sleep", 500)); -return 1 +return Integer.getInteger("byteman.jpaaudit.delete", 1) ENDRULE +######################################################################## +# +# Rule to slow down the execution of JPAAuditLogService.doPartialDelete +# + +RULE JPAAuditLogService.doPartialDelete sleep +CLASS org.jbpm.process.audit.JPAAuditLogService +METHOD doPartialDelete +AT ENTRY +IF TRUE +DO debug("Pausing JPAAuditLogService.doPartialDelete for " + Integer.getInteger("byteman.jpaaudit.sleep", 500) + "ms"); +Thread.sleep(Integer.getInteger("byteman.jpaaudit.sleep", 500)); +return Integer.getInteger("byteman.jpaaudit.delete", 1) +ENDRULE