public Object execute(CommandContext commandContext) { ensureNotNull("jobId", jobId); JobEntity job = commandContext.getJobManager().findJobById(jobId); ensureNotNull("No job found with id '" + jobId + "'", "job", job); for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { checker.checkUpdateJob(job); } // We need to check if the job was locked, ie acquired by the job acquisition thread // This happens if the the job was already acquired, but not yet executed. // In that case, we can't allow to delete the job. if (job.getLockOwner() != null || job.getLockExpirationTime() != null) { throw new ProcessEngineException("Cannot delete job when the job is being executed. Try again later."); } job.delete(); return null; }
public Object execute(CommandContext commandContext) { ensureNotNull("jobId", jobId); JobEntity job = commandContext.getJobManager().findJobById(jobId); ensureNotNull("No job found with id '" + jobId + "'", "job", job); for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { checker.checkUpdateJob(job); } // We need to check if the job was locked, ie acquired by the job acquisition thread // This happens if the the job was already acquired, but not yet executed. // In that case, we can't allow to delete the job. if (job.getLockOwner() != null || job.getLockExpirationTime() != null) { throw new ProcessEngineException("Cannot delete job when the job is being executed. Try again later."); } job.delete(); return null; }
@Test @org.camunda.bpm.engine.test.Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/IncidentTest.testShouldCreateOneIncident.bpmn"}) public void testFailedJobListenerRetries() { //given runtimeService.startProcessInstanceByKey("failingProcess"); //when the job is run several times till the incident creation Job job = getJob(); while (job.getRetries() > 0 && ((JobEntity)job).getLockOwner() == null ) { try { lockTheJob(job.getId()); engineRule.getManagementService().executeJob(job.getId()); } catch (Exception ex) { } job = getJob(); } //then JobEntity jobFinalState = (JobEntity)engineRule.getManagementService().createJobQuery().jobId(job.getId()).list().get(0); assertEquals(jobRetries, jobFinalState.getRetries()); if (jobLocked) { assertNotNull(jobFinalState.getLockOwner()); assertNotNull(jobFinalState.getLockExpirationTime()); } else { assertNull(jobFinalState.getLockOwner()); assertNull(jobFinalState.getLockExpirationTime()); } }
@Test @Deployment public void testCompetingJobExecutionDefaultRetryStrategy() { // given an MI subprocess with two instances runtimeService.startProcessInstanceByKey("miParallelSubprocess"); List<Job> currentJobs = managementService.createJobQuery().list(); assertEquals(2, currentJobs.size()); // when the jobs are executed in parallel JobExecutionThread threadOne = new JobExecutionThread(currentJobs.get(0).getId()); threadOne.startAndWaitUntilControlIsReturned(); JobExecutionThread threadTwo = new JobExecutionThread(currentJobs.get(1).getId()); threadTwo.startAndWaitUntilControlIsReturned(); // then the first committing thread succeeds LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // then the second committing thread fails with an OptimisticLockingException // and the job retries have not been decremented LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); assertNotNull(threadTwo.exception); Job remainingJob = managementService.createJobQuery().singleResult(); assertEquals(currentJobs.get(1).getRetries(), remainingJob.getRetries()); assertNotNull(remainingJob.getExceptionMessage()); JobEntity jobEntity = (JobEntity) remainingJob; assertNull(jobEntity.getLockOwner()); // and there is no lock expiration time due to the default retry strategy assertNull(jobEntity.getLockExpirationTime()); }
@Test @Deployment public void testCompetingJobExecutionFoxRetryStrategy() { // given an MI subprocess with two instances runtimeService.startProcessInstanceByKey("miParallelSubprocess"); List<Job> currentJobs = managementService.createJobQuery().list(); assertEquals(2, currentJobs.size()); // when the jobs are executed in parallel JobExecutionThread threadOne = new JobExecutionThread(currentJobs.get(0).getId()); threadOne.startAndWaitUntilControlIsReturned(); JobExecutionThread threadTwo = new JobExecutionThread(currentJobs.get(1).getId()); threadTwo.startAndWaitUntilControlIsReturned(); // then the first committing thread succeeds LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // then the second committing thread fails with an OptimisticLockingException // and the job retries have not been decremented LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); assertNotNull(threadTwo.exception); Job remainingJob = managementService.createJobQuery().singleResult(); // retries are configured as R5/PT5M, so no decrement means 5 retries left assertEquals(5, remainingJob.getRetries()); assertNotNull(remainingJob.getExceptionMessage()); JobEntity jobEntity = (JobEntity) remainingJob; assertNull(jobEntity.getLockOwner()); // and there is a custom lock expiration time assertNotNull(jobEntity.getLockExpirationTime()); }
for(Job job : lockedJobList) { JobEntity jobEntity = (JobEntity)job; Assert.assertNotNull(jobEntity.getLockOwner()); Assert.assertNotNull(jobEntity); Assert.assertTrue(lockedJobList.get(1).getId().equals(jobEntity.getId()) || lockedJobList.get(0).getId().equals(jobEntity.getId())); Assert.assertNull(jobEntity.getLockOwner()); Assert.assertNull(jobEntity.getLockExpirationTime());
@Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"}) public void testSetJobRetriesByDefinitionUnlocksInconsistentJobs() { // given a job definition final JobDefinition jobDefinition = managementService.createJobDefinitionQuery().singleResult(); // and an inconsistent job that is never again picked up by a job executor CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired(); commandExecutor.execute(new Command<Void>() { @Override public Void execute(CommandContext commandContext) { JobManager jobManager = commandContext.getJobManager(); MessageEntity job = new MessageEntity(); job.setJobDefinitionId(jobDefinition.getId()); job.setJobHandlerType("any"); job.setLockOwner("owner"); job.setLockExpirationTime(ClockUtil.getCurrentTime()); job.setRetries(0); jobManager.send(job); return null; } }); // when the job retries are reset managementService.setJobRetriesByJobDefinitionId(jobDefinition.getId(), 3); // then the job can be picked up again JobEntity job = (JobEntity) managementService.createJobQuery().singleResult(); assertNotNull(job); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); deleteJobAndIncidents(job); }
assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); assertNotNull(job.getLockOwner()); assertNotNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries());
Assert.assertNotNull(secondAsyncJob); Assert.assertFalse(secondAsyncJob.getId().equals(firstAsyncJob.getId())); Assert.assertNull(secondAsyncJob.getLockOwner()); Assert.assertNull(secondAsyncJob.getLockExpirationTime());
@Test public void testExecuteExclusiveFollowUpJobInDifferentProcessInstance() { testHelper.deploy(CALL_ACTIVITY_PROCESS, ONE_TASK_PROCESS); // given // a process instance with a single job ProcessInstance processInstance = engineRule.getRuntimeService().startProcessInstanceByKey("callActivityProcess"); jobExecutor.start(); // and first job acquisition that acquires the job acquisitionThread.waitForSync(); acquisitionThread.makeContinueAndWaitForSync(); // and job is executed acquisitionThread.makeContinueAndWaitForSync(); // then // the called instance has been created ProcessInstance calledInstance = engineRule.getRuntimeService() .createProcessInstanceQuery() .superProcessInstanceId(processInstance.getId()) .singleResult(); Assert.assertNotNull(calledInstance); // and there is a transition instance for the service task ActivityInstance activityInstance = engineRule.getRuntimeService().getActivityInstance(calledInstance.getId()); Assert.assertEquals(1, activityInstance.getTransitionInstances("serviceTask").length); // but the corresponding job is not locked JobEntity followUpJob = (JobEntity) engineRule.getManagementService().createJobQuery().singleResult(); Assert.assertNotNull(followUpJob); Assert.assertNull(followUpJob.getLockOwner()); Assert.assertNull(followUpJob.getLockExpirationTime()); }
Assert.assertNotNull(followUpJob.getLockOwner()); Assert.assertNotNull(followUpJob.getLockExpirationTime());
public Object execute(CommandContext commandContext) { ensureNotNull("jobId", jobId); JobEntity job = commandContext.getJobManager().findJobById(jobId); ensureNotNull("No job found with id '" + jobId + "'", "job", job); for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { checker.checkUpdateJob(job); } // We need to check if the job was locked, ie acquired by the job acquisition thread // This happens if the the job was already acquired, but not yet executed. // In that case, we can't allow to delete the job. if (job.getLockOwner() != null || job.getLockExpirationTime() != null) { throw new ProcessEngineException("Cannot delete job when the job is being executed. Try again later."); } job.delete(); return null; }
@Test @org.camunda.bpm.engine.test.Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/IncidentTest.testShouldCreateOneIncident.bpmn"}) public void testFailedJobListenerRetries() { //given runtimeService.startProcessInstanceByKey("failingProcess"); //when the job is run several times till the incident creation Job job = getJob(); while (job.getRetries() > 0 && ((JobEntity)job).getLockOwner() == null ) { try { lockTheJob(job.getId()); engineRule.getManagementService().executeJob(job.getId()); } catch (Exception ex) { } job = getJob(); } //then JobEntity jobFinalState = (JobEntity)engineRule.getManagementService().createJobQuery().jobId(job.getId()).list().get(0); assertEquals(jobRetries, jobFinalState.getRetries()); if (jobLocked) { assertNotNull(jobFinalState.getLockOwner()); assertNotNull(jobFinalState.getLockExpirationTime()); } else { assertNull(jobFinalState.getLockOwner()); assertNull(jobFinalState.getLockExpirationTime()); } }
@Test @Deployment public void testCompetingJobExecutionDefaultRetryStrategy() { // given an MI subprocess with two instances runtimeService.startProcessInstanceByKey("miParallelSubprocess"); List<Job> currentJobs = managementService.createJobQuery().list(); assertEquals(2, currentJobs.size()); // when the jobs are executed in parallel JobExecutionThread threadOne = new JobExecutionThread(currentJobs.get(0).getId()); threadOne.startAndWaitUntilControlIsReturned(); JobExecutionThread threadTwo = new JobExecutionThread(currentJobs.get(1).getId()); threadTwo.startAndWaitUntilControlIsReturned(); // then the first committing thread succeeds LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // then the second committing thread fails with an OptimisticLockingException // and the job retries have not been decremented LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); assertNotNull(threadTwo.exception); Job remainingJob = managementService.createJobQuery().singleResult(); assertEquals(currentJobs.get(1).getRetries(), remainingJob.getRetries()); assertNotNull(remainingJob.getExceptionMessage()); JobEntity jobEntity = (JobEntity) remainingJob; assertNull(jobEntity.getLockOwner()); // and there is no lock expiration time due to the default retry strategy assertNull(jobEntity.getLockExpirationTime()); }
@Test @Deployment public void testCompetingJobExecutionFoxRetryStrategy() { // given an MI subprocess with two instances runtimeService.startProcessInstanceByKey("miParallelSubprocess"); List<Job> currentJobs = managementService.createJobQuery().list(); assertEquals(2, currentJobs.size()); // when the jobs are executed in parallel JobExecutionThread threadOne = new JobExecutionThread(currentJobs.get(0).getId()); threadOne.startAndWaitUntilControlIsReturned(); JobExecutionThread threadTwo = new JobExecutionThread(currentJobs.get(1).getId()); threadTwo.startAndWaitUntilControlIsReturned(); // then the first committing thread succeeds LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // then the second committing thread fails with an OptimisticLockingException // and the job retries have not been decremented LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); assertNotNull(threadTwo.exception); Job remainingJob = managementService.createJobQuery().singleResult(); // retries are configured as R5/PT5M, so no decrement means 5 retries left assertEquals(5, remainingJob.getRetries()); assertNotNull(remainingJob.getExceptionMessage()); JobEntity jobEntity = (JobEntity) remainingJob; assertNull(jobEntity.getLockOwner()); // and there is a custom lock expiration time assertNotNull(jobEntity.getLockExpirationTime()); }
for(Job job : lockedJobList) { JobEntity jobEntity = (JobEntity)job; Assert.assertNotNull(jobEntity.getLockOwner()); Assert.assertNotNull(jobEntity); Assert.assertTrue(lockedJobList.get(1).getId().equals(jobEntity.getId()) || lockedJobList.get(0).getId().equals(jobEntity.getId())); Assert.assertNull(jobEntity.getLockOwner()); Assert.assertNull(jobEntity.getLockExpirationTime());
@Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"}) public void testSetJobRetriesByDefinitionUnlocksInconsistentJobs() { // given a job definition final JobDefinition jobDefinition = managementService.createJobDefinitionQuery().singleResult(); // and an inconsistent job that is never again picked up by a job executor CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired(); commandExecutor.execute(new Command<Void>() { @Override public Void execute(CommandContext commandContext) { JobManager jobManager = commandContext.getJobManager(); MessageEntity job = new MessageEntity(); job.setJobDefinitionId(jobDefinition.getId()); job.setJobHandlerType("any"); job.setLockOwner("owner"); job.setLockExpirationTime(ClockUtil.getCurrentTime()); job.setRetries(0); jobManager.send(job); return null; } }); // when the job retries are reset managementService.setJobRetriesByJobDefinitionId(jobDefinition.getId(), 3); // then the job can be picked up again JobEntity job = (JobEntity) managementService.createJobQuery().singleResult(); assertNotNull(job); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); deleteJobAndIncidents(job); }
Assert.assertNotNull(secondAsyncJob); Assert.assertFalse(secondAsyncJob.getId().equals(firstAsyncJob.getId())); Assert.assertNull(secondAsyncJob.getLockOwner()); Assert.assertNull(secondAsyncJob.getLockExpirationTime());
@Test public void testExecuteExclusiveFollowUpJobInDifferentProcessInstance() { testHelper.deploy(CALL_ACTIVITY_PROCESS, ONE_TASK_PROCESS); // given // a process instance with a single job ProcessInstance processInstance = engineRule.getRuntimeService().startProcessInstanceByKey("callActivityProcess"); jobExecutor.start(); // and first job acquisition that acquires the job acquisitionThread.waitForSync(); acquisitionThread.makeContinueAndWaitForSync(); // and job is executed acquisitionThread.makeContinueAndWaitForSync(); // then // the called instance has been created ProcessInstance calledInstance = engineRule.getRuntimeService() .createProcessInstanceQuery() .superProcessInstanceId(processInstance.getId()) .singleResult(); Assert.assertNotNull(calledInstance); // and there is a transition instance for the service task ActivityInstance activityInstance = engineRule.getRuntimeService().getActivityInstance(calledInstance.getId()); Assert.assertEquals(1, activityInstance.getTransitionInstances("serviceTask").length); // but the corresponding job is not locked JobEntity followUpJob = (JobEntity) engineRule.getManagementService().createJobQuery().singleResult(); Assert.assertNotNull(followUpJob); Assert.assertNull(followUpJob.getLockOwner()); Assert.assertNull(followUpJob.getLockExpirationTime()); }
Assert.assertNotNull(followUpJob.getLockOwner()); Assert.assertNotNull(followUpJob.getLockExpirationTime());