public void acquiredJobs(String processEngine, AcquiredJobs acquiredJobs) { logDebug( "022", "Acquired {} jobs for process engine '{}': {}", acquiredJobs.size(), processEngine, acquiredJobs.getJobIdBatches()); }
public void testAcquiredJobs() { List<String> firstBatch = new ArrayList<String>(Arrays.asList("a", "b", "c")); List<String> secondBatch = new ArrayList<String>(Arrays.asList("d", "e", "f")); List<String> thirdBatch = new ArrayList<String>(Arrays.asList("g")); AcquiredJobs acquiredJobs = new AcquiredJobs(0); acquiredJobs.addJobIdBatch(firstBatch); acquiredJobs.addJobIdBatch(secondBatch); acquiredJobs.addJobIdBatch(thirdBatch); assertEquals(firstBatch, acquiredJobs.getJobIdBatches().get(0)); assertEquals(secondBatch, acquiredJobs.getJobIdBatches().get(1)); assertEquals(thirdBatch, acquiredJobs.getJobIdBatches().get(2)); acquiredJobs.removeJobId("a"); assertEquals(Arrays.asList("b", "c"), acquiredJobs.getJobIdBatches().get(0)); assertEquals(secondBatch, acquiredJobs.getJobIdBatches().get(1)); assertEquals(thirdBatch, acquiredJobs.getJobIdBatches().get(2)); assertEquals(3, acquiredJobs.getJobIdBatches().size()); acquiredJobs.removeJobId("g"); assertEquals(2, acquiredJobs.getJobIdBatches().size()); } }
/** * @return true, if for all engines there were less jobs acquired than requested */ public boolean areAllEnginesIdle() { for (AcquiredJobs acquiredJobs : acquiredJobsByEngine.values()) { int jobsAcquired = acquiredJobs.getJobIdBatches().size() + acquiredJobs.getNumberOfJobsFailedToLock(); if (jobsAcquired >= acquiredJobs.getNumberOfJobsAttemptedToAcquire()) { return false; } } return true; }
/** * numJobsToAcquire >= numJobsAcquired >= numJobsFailedToLock must hold */ protected AcquiredJobs buildAcquiredJobs(int numJobsToAcquire, int numJobsAcquired, int numJobsFailedToLock) { AcquiredJobs acquiredJobs = new AcquiredJobs(numJobsToAcquire); for (int i = 0; i < numJobsAcquired; i++) { acquiredJobs.addJobIdBatch(Arrays.asList(Integer.toString(i))); } for (int i = 0; i < numJobsFailedToLock; i++) { acquiredJobs.removeJobId(Integer.toString(i)); } return acquiredJobs; }
public void testJobsWithoutDeploymentIdAreAlwaysProcessed() { CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired(); String messageId = commandExecutor.execute(new Command<String>() { public String execute(CommandContext commandContext) { MessageEntity message = new MessageEntity(); commandContext.getJobManager().send(message); return message.getId(); } }); AcquiredJobs acquiredJobs = getExecutableJobs(processEngineConfiguration.getJobExecutor()); Assert.assertEquals(1, acquiredJobs.size()); Assert.assertTrue(acquiredJobs.contains(messageId)); commandExecutor.execute(new DeleteJobsCmd(messageId, true)); }
protected AcquiredJobs acquireJobs( JobAcquisitionContext context, JobAcquisitionStrategy acquisitionStrategy, ProcessEngineImpl currentProcessEngine) { CommandExecutor commandExecutor = currentProcessEngine.getProcessEngineConfiguration() .getCommandExecutorTxRequired(); int numJobsToAcquire = acquisitionStrategy.getNumJobsToAcquire(currentProcessEngine.getName()); AcquiredJobs acquiredJobs = null; if (numJobsToAcquire > 0) { jobExecutor.logAcquisitionAttempt(currentProcessEngine); acquiredJobs = commandExecutor.execute(jobExecutor.getAcquireJobsCmd(numJobsToAcquire)); } else { acquiredJobs = new AcquiredJobs(numJobsToAcquire); } context.submitAcquiredJobs(currentProcessEngine.getName(), acquiredJobs); jobExecutor.logAcquiredJobs(currentProcessEngine, acquiredJobs.size()); jobExecutor.logAcquisitionFailureJobs(currentProcessEngine, acquiredJobs.getNumberOfJobsFailedToLock()); LOG.acquiredJobs(currentProcessEngine.getName(), acquiredJobs); return acquiredJobs; }
@Deployment public void testCompetingJobAcquisitions() throws Exception { runtimeService.startProcessInstanceByKey("CompetingJobAcquisitionProcess"); LOG.debug("test thread starts thread one"); JobAcquisitionThread threadOne = new JobAcquisitionThread(); threadOne.startAndWaitUntilControlIsReturned(); LOG.debug("test thread continues to start thread two"); JobAcquisitionThread threadTwo = new JobAcquisitionThread(); threadTwo.startAndWaitUntilControlIsReturned(); LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // the job was acquired assertEquals(1, threadOne.jobs.size()); LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); // the acquisition did NOT fail assertNull(threadTwo.exception); // but the job was not acquired assertEquals(0, threadTwo.jobs.size()); }
/** * @return true, if all acquired jobs (spanning all engines) were rejected for execution */ protected boolean allSubmittedJobsRejected(JobAcquisitionContext context) { for (Map.Entry<String, AcquiredJobs> acquiredJobsForEngine : context.getAcquiredJobsByEngine().entrySet()) { String engineName = acquiredJobsForEngine.getKey(); List<List<String>> acquiredJobBatches = acquiredJobsForEngine.getValue().getJobIdBatches(); List<List<String>> resubmittedJobBatches = context.getAdditionalJobsByEngine().get(engineName); List<List<String>> rejectedJobBatches = context.getRejectedJobsByEngine().get(engineName); int numJobsSubmittedForExecution = acquiredJobBatches.size(); if (resubmittedJobBatches != null) { numJobsSubmittedForExecution += resubmittedJobBatches.size(); } int numJobsRejected = 0; if (rejectedJobBatches != null) { numJobsRejected += rejectedJobBatches.size(); } // if not all jobs scheduled for execution have been rejected if (numJobsRejected == 0 || numJobsSubmittedForExecution > numJobsRejected) { return false; } } return true; }
public AcquiredJobs execute(CommandContext commandContext) { acquiredJobs = new AcquiredJobs(numJobsToAcquire); List<JobEntity> jobs = commandContext .getJobManager() .findNextJobsToExecute(new Page(0, numJobsToAcquire)); Map<String, List<String>> exclusiveJobsByProcessInstance = new HashMap<String, List<String>>(); for (JobEntity job : jobs) { lockJob(job); if(job.isExclusive()) { List<String> list = exclusiveJobsByProcessInstance.get(job.getProcessInstanceId()); if (list == null) { list = new ArrayList<String>(); exclusiveJobsByProcessInstance.put(job.getProcessInstanceId(), list); } list.add(job.getId()); } else { acquiredJobs.addJobIdBatch(job.getId()); } } for (List<String> jobIds : exclusiveJobsByProcessInstance.values()) { acquiredJobs.addJobIdBatch(jobIds); } // register an OptimisticLockingListener which is notified about jobs which cannot be acquired. // the listener removes them from the list of acquired jobs. commandContext .getDbEntityManager() .registerOptimisticLockingListener(this); return acquiredJobs; }
public void addJobIdBatch(String jobId) { ArrayList<String> list = new ArrayList<String>(); list.add(jobId); addJobIdBatch(list); }
public void failedOperation(DbOperation operation) { if (operation instanceof DbEntityOperation) { DbEntityOperation entityOperation = (DbEntityOperation) operation; if(JobEntity.class.isAssignableFrom(entityOperation.getEntityType())) { // could not lock the job -> remove it from list of acquired jobs acquiredJobs.removeJobId(entityOperation.getEntity().getId()); } } }
/** * true if at least one job could not be locked, regardless of engine */ public boolean hasJobAcquisitionLockFailureOccurred() { for (AcquiredJobs acquiredJobs : acquiredJobsByEngine.values()) { if (acquiredJobs.getNumberOfJobsFailedToLock() > 0) { return true; } } return false; }
@Deployment(resources = "org/camunda/bpm/engine/test/jobexecutor/simpleAsyncProcess.bpmn20.xml") public void testProcessingOfJobsWithMatchingDeployment() { runtimeService.startProcessInstanceByKey("simpleAsyncProcess"); Set<String> registeredDeployments = managementService.getRegisteredDeployments(); Assert.assertEquals(1, registeredDeployments.size()); Assert.assertTrue(registeredDeployments.contains(deploymentId)); Job executableJob = managementService.createJobQuery().singleResult(); String otherDeploymentId = deployAndInstantiateWithNewEngineConfiguration( "org/camunda/bpm/engine/test/jobexecutor/simpleAsyncProcessVersion2.bpmn20.xml"); // assert that two jobs have been created, one for each deployment List<Job> jobs = managementService.createJobQuery().list(); Assert.assertEquals(2, jobs.size()); Set<String> jobDeploymentIds = new HashSet<String>(); jobDeploymentIds.add(jobs.get(0).getDeploymentId()); jobDeploymentIds.add(jobs.get(1).getDeploymentId()); Assert.assertTrue(jobDeploymentIds.contains(deploymentId)); Assert.assertTrue(jobDeploymentIds.contains(otherDeploymentId)); // select executable jobs for executor of first engine AcquiredJobs acquiredJobs = getExecutableJobs(processEngineConfiguration.getJobExecutor()); Assert.assertEquals(1, acquiredJobs.size()); Assert.assertTrue(acquiredJobs.contains(executableJob.getId())); repositoryService.deleteDeployment(otherDeploymentId, true); }
protected AcquiredJobs acquireJobs( JobAcquisitionContext context, JobAcquisitionStrategy acquisitionStrategy, ProcessEngineImpl currentProcessEngine) { CommandExecutor commandExecutor = currentProcessEngine.getProcessEngineConfiguration() .getCommandExecutorTxRequired(); int numJobsToAcquire = acquisitionStrategy.getNumJobsToAcquire(currentProcessEngine.getName()); AcquiredJobs acquiredJobs = null; if (numJobsToAcquire > 0) { jobExecutor.logAcquisitionAttempt(currentProcessEngine); acquiredJobs = commandExecutor.execute(jobExecutor.getAcquireJobsCmd(numJobsToAcquire)); } else { acquiredJobs = new AcquiredJobs(numJobsToAcquire); } context.submitAcquiredJobs(currentProcessEngine.getName(), acquiredJobs); jobExecutor.logAcquiredJobs(currentProcessEngine, acquiredJobs.size()); jobExecutor.logAcquisitionFailureJobs(currentProcessEngine, acquiredJobs.getNumberOfJobsFailedToLock()); LOG.acquiredJobs(currentProcessEngine.getName(), acquiredJobs); return acquiredJobs; }
@Test public void testJobExecutorOnlyAcquiresActiveJobs() { testRule.deploy(SIMPLE_ASYNC_PROCESS); // given suspended job definition: managementService.suspendJobDefinitionByProcessDefinitionKey("simpleAsyncProcess"); // if I start a new instance runtimeService.startProcessInstanceByKey("simpleAsyncProcess"); // then the new job executor will not acquire the job: AcquiredJobs acquiredJobs = acquireJobs(); assertEquals(0, acquiredJobs.size()); // ------------------------- // given a active job definition: managementService.activateJobDefinitionByProcessDefinitionKey("simpleAsyncProcess", true); // then the new job executor will not acquire the job: acquiredJobs = acquireJobs(); assertEquals(1, acquiredJobs.size()); }
/** * numJobsToAcquire >= numJobsAcquired >= numJobsFailedToLock must hold */ protected AcquiredJobs buildAcquiredJobs(int numJobsToAcquire, int numJobsAcquired, int numJobsFailedToLock) { AcquiredJobs acquiredJobs = new AcquiredJobs(numJobsToAcquire); for (int i = 0; i < numJobsAcquired; i++) { acquiredJobs.addJobIdBatch(Arrays.asList(Integer.toString(i))); } for (int i = 0; i < numJobsFailedToLock; i++) { acquiredJobs.removeJobId(Integer.toString(i)); } return acquiredJobs; }
/** * @return true, if all acquired jobs (spanning all engines) were rejected for execution */ protected boolean allSubmittedJobsRejected(JobAcquisitionContext context) { for (Map.Entry<String, AcquiredJobs> acquiredJobsForEngine : context.getAcquiredJobsByEngine().entrySet()) { String engineName = acquiredJobsForEngine.getKey(); List<List<String>> acquiredJobBatches = acquiredJobsForEngine.getValue().getJobIdBatches(); List<List<String>> resubmittedJobBatches = context.getAdditionalJobsByEngine().get(engineName); List<List<String>> rejectedJobBatches = context.getRejectedJobsByEngine().get(engineName); int numJobsSubmittedForExecution = acquiredJobBatches.size(); if (resubmittedJobBatches != null) { numJobsSubmittedForExecution += resubmittedJobBatches.size(); } int numJobsRejected = 0; if (rejectedJobBatches != null) { numJobsRejected += rejectedJobBatches.size(); } // if not all jobs scheduled for execution have been rejected if (numJobsRejected == 0 || numJobsSubmittedForExecution > numJobsRejected) { return false; } } return true; }
public AcquiredJobs execute(CommandContext commandContext) { acquiredJobs = new AcquiredJobs(numJobsToAcquire); List<JobEntity> jobs = commandContext .getJobManager() .findNextJobsToExecute(new Page(0, numJobsToAcquire)); Map<String, List<String>> exclusiveJobsByProcessInstance = new HashMap<String, List<String>>(); for (JobEntity job : jobs) { lockJob(job); if(job.isExclusive()) { List<String> list = exclusiveJobsByProcessInstance.get(job.getProcessInstanceId()); if (list == null) { list = new ArrayList<String>(); exclusiveJobsByProcessInstance.put(job.getProcessInstanceId(), list); } list.add(job.getId()); } else { acquiredJobs.addJobIdBatch(job.getId()); } } for (List<String> jobIds : exclusiveJobsByProcessInstance.values()) { acquiredJobs.addJobIdBatch(jobIds); } // register an OptimisticLockingListener which is notified about jobs which cannot be acquired. // the listener removes them from the list of acquired jobs. commandContext .getDbEntityManager() .registerOptimisticLockingListener(this); return acquiredJobs; }
public void addJobIdBatch(String jobId) { ArrayList<String> list = new ArrayList<String>(); list.add(jobId); addJobIdBatch(list); }
public void failedOperation(DbOperation operation) { if (operation instanceof DbEntityOperation) { DbEntityOperation entityOperation = (DbEntityOperation) operation; if(JobEntity.class.isAssignableFrom(entityOperation.getEntityType())) { // could not lock the job -> remove it from list of acquired jobs acquiredJobs.removeJobId(entityOperation.getEntity().getId()); } } }