protected JobAcquisitionContext initializeAcquisitionContext() { return new JobAcquisitionContext(); }
@Override public void jobsRejected(List<String> jobIds, ProcessEngineImpl processEngine, JobExecutor jobExecutor) { AcquireJobsRunnable acquireJobsRunnable = jobExecutor.getAcquireJobsRunnable(); if (acquireJobsRunnable instanceof SequentialJobAcquisitionRunnable) { JobAcquisitionContext context = ((SequentialJobAcquisitionRunnable) acquireJobsRunnable).getAcquisitionContext(); context.submitRejectedBatch(processEngine.getName(), jobIds); } else { jobExecutor.getExecuteJobsRunnable(jobIds, processEngine).run(); } }
protected void reconfigureIdleLevel(JobAcquisitionContext context) { if (context.isJobAdded()) { idleLevel = 0; } else { if (context.areAllEnginesIdle() || context.getAcquisitionException() != null) { if (idleLevel < maxIdleLevel) { idleLevel++; } } else { idleLevel = 0; } } }
protected void reconfigureNumberOfJobsToAcquire(JobAcquisitionContext context) { // calculate the number of jobs to acquire next time jobsToAcquire.clear(); for (Map.Entry<String, AcquiredJobs> acquiredJobsEntry : context.getAcquiredJobsByEngine().entrySet()) { String engineName = acquiredJobsEntry.getKey(); int numJobsToAcquire = (int) (baseNumJobsToAcquire * Math.pow(backoffIncreaseFactor, backoffLevel)); List<List<String>> rejectedJobBatchesForEngine = context.getRejectedJobsByEngine().get(engineName); if (rejectedJobBatchesForEngine != null) { numJobsToAcquire -= rejectedJobBatchesForEngine.size(); } numJobsToAcquire = Math.max(0, numJobsToAcquire); jobsToAcquire.put(engineName, numJobsToAcquire); } }
/** * @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; }
acquisitionContext.reset(); acquisitionContext.setAcquisitionTime(System.currentTimeMillis()); LOG.exceptionDuringJobAcquisition(e); acquisitionContext.setAcquisitionException(e); acquisitionContext.setJobAdded(isJobAdded); configureNextAcquisitionCycle(acquisitionContext, acquisitionStrategy); waitTime = Math.max(0, (acquisitionContext.getAcquisitionTime() + waitTime) - System.currentTimeMillis());
@Test public void testAcquisitionAfterIdleWait() { // given a job acquisition strategy and a job acquisition context // with no acquired jobs JobAcquisitionContext context = new JobAcquisitionContext(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, 0, 0)); strategy.reconfigure(context); Assert.assertEquals(BASE_IDLE_WAIT_TIME, strategy.getWaitTime()); // when receiving a successful acquisition result context.reset(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, NUM_JOBS_TO_ACQUIRE, 0)); strategy.reconfigure(context); // then the idle wait time has been reset Assert.assertEquals(0L, strategy.getWaitTime()); }
@Test public void testWaitTimeOnFullRejection() { // given a job acquisition strategy and a job acquisition context // with acquired jobs all of which have been rejected for execution JobAcquisitionContext context = new JobAcquisitionContext(); AcquiredJobs acquiredJobs = buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, NUM_JOBS_TO_ACQUIRE, 0); context.submitAcquiredJobs(ENGINE_NAME, acquiredJobs); for (int i = 0; i < NUM_JOBS_TO_ACQUIRE; i++) { context.submitRejectedBatch(ENGINE_NAME, acquiredJobs.getJobIdBatches().get(i)); } // when reconfiguring the strategy strategy.reconfigure(context); // then there is a slight wait time to avoid constant spinning while // no execution resources are available Assert.assertEquals(BackoffJobAcquisitionStrategy.DEFAULT_EXECUTION_SATURATION_WAIT_TIME, strategy.getWaitTime()); }
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; }
acquisitionContext.reset(); acquisitionContext.setAcquisitionTime(System.currentTimeMillis()); LOG.exceptionDuringJobAcquisition(e); acquisitionContext.setAcquisitionException(e); acquisitionContext.setJobAdded(isJobAdded); configureNextAcquisitionCycle(acquisitionContext, acquisitionStrategy); waitTime = Math.max(0, (acquisitionContext.getAcquisitionTime() + waitTime) - System.currentTimeMillis());
@Test public void testIdleWaitTime() { // given a job acquisition strategy and a job acquisition context // with no acquired jobs JobAcquisitionContext context = new JobAcquisitionContext(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, 0, 0)); // when reconfiguring the strategy strategy.reconfigure(context); // then the job acquisition strategy returns the level 1 idle time Assert.assertEquals(BASE_IDLE_WAIT_TIME, strategy.getWaitTime()); // when resubmitting the same acquisition result for (int idleLevel = 1; idleLevel < 6; idleLevel++) { context.reset(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, 0, 0)); strategy.reconfigure(context); Assert.assertEquals((long) (BASE_IDLE_WAIT_TIME * Math.pow(IDLE_INCREASE_FACTOR, idleLevel)), strategy.getWaitTime()); } // and the maximum idle level is finally reached context.reset(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, 0, 0)); strategy.reconfigure(context); Assert.assertEquals(MAX_IDLE_TIME, strategy.getWaitTime()); }
@Test public void testAcquireLessJobsOnRejection() { // given a job acquisition strategy and a job acquisition context // with acquired jobs, some of which have been rejected for execution JobAcquisitionContext context = new JobAcquisitionContext(); AcquiredJobs acquiredJobs = buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, NUM_JOBS_TO_ACQUIRE, 0); context.submitAcquiredJobs(ENGINE_NAME, acquiredJobs); // when half of the jobs are rejected int numJobsRejected = 5; for (int i = 0; i < numJobsRejected; i++) { context.submitRejectedBatch(ENGINE_NAME, acquiredJobs.getJobIdBatches().get(i)); } // then the strategy only attempts to acquire the number of jobs that were successfully submitted strategy.reconfigure(context); Assert.assertEquals(NUM_JOBS_TO_ACQUIRE - numJobsRejected, strategy.getNumJobsToAcquire(ENGINE_NAME)); // without a timeout Assert.assertEquals(0, strategy.getWaitTime()); }
/** * @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; }
protected void reconfigureNumberOfJobsToAcquire(JobAcquisitionContext context) { // calculate the number of jobs to acquire next time jobsToAcquire.clear(); for (Map.Entry<String, AcquiredJobs> acquiredJobsEntry : context.getAcquiredJobsByEngine().entrySet()) { String engineName = acquiredJobsEntry.getKey(); int numJobsToAcquire = (int) (baseNumJobsToAcquire * Math.pow(backoffIncreaseFactor, backoffLevel)); List<List<String>> rejectedJobBatchesForEngine = context.getRejectedJobsByEngine().get(engineName); if (rejectedJobBatchesForEngine != null) { numJobsToAcquire -= rejectedJobBatchesForEngine.size(); } numJobsToAcquire = Math.max(0, numJobsToAcquire); jobsToAcquire.put(engineName, numJobsToAcquire); } }
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; }
@Override public synchronized void run() { acquisitionContext.reset(); acquisitionContext.setAcquisitionTime(System.currentTimeMillis()); logger.error("Exception during Aquisition", e); acquisitionContext.setAcquisitionException(e); acquisitionContext.setJobAdded(isJobAdded); configureNextAcquisitionCycle(acquisitionContext, acquisitionStrategy); waitTime = Math.max(0, (acquisitionContext.getAcquisitionTime() + waitTime) - System.currentTimeMillis());
@Test public void testAcquisitionAfterIdleWait() { // given a job acquisition strategy and a job acquisition context // with no acquired jobs JobAcquisitionContext context = new JobAcquisitionContext(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, 0, 0)); strategy.reconfigure(context); Assert.assertEquals(BASE_IDLE_WAIT_TIME, strategy.getWaitTime()); // when receiving a successful acquisition result context.reset(); context.submitAcquiredJobs(ENGINE_NAME, buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, NUM_JOBS_TO_ACQUIRE, 0)); strategy.reconfigure(context); // then the idle wait time has been reset Assert.assertEquals(0L, strategy.getWaitTime()); }
@Test public void testWaitTimeOnFullRejection() { // given a job acquisition strategy and a job acquisition context // with acquired jobs all of which have been rejected for execution JobAcquisitionContext context = new JobAcquisitionContext(); AcquiredJobs acquiredJobs = buildAcquiredJobs(NUM_JOBS_TO_ACQUIRE, NUM_JOBS_TO_ACQUIRE, 0); context.submitAcquiredJobs(ENGINE_NAME, acquiredJobs); for (int i = 0; i < NUM_JOBS_TO_ACQUIRE; i++) { context.submitRejectedBatch(ENGINE_NAME, acquiredJobs.getJobIdBatches().get(i)); } // when reconfiguring the strategy strategy.reconfigure(context); // then there is a slight wait time to avoid constant spinning while // no execution resources are available Assert.assertEquals(BackoffJobAcquisitionStrategy.DEFAULT_EXECUTION_SATURATION_WAIT_TIME, strategy.getWaitTime()); }
protected void reconfigureIdleLevel(JobAcquisitionContext context) { if (context.isJobAdded()) { idleLevel = 0; } else { if (context.areAllEnginesIdle() || context.getAcquisitionException() != null) { if (idleLevel < maxIdleLevel) { idleLevel++; } } else { idleLevel = 0; } } }
/** * @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; }