protected virtual AcquiredJobs AcquireJobs(JobAcquisitionContext context, IJobAcquisitionStrategy acquisitionStrategy, ProcessEngineImpl currentProcessEngine) { ICommandExecutor commandExecutor = ((ProcessEngineConfigurationImpl)currentProcessEngine.ProcessEngineConfiguration).CommandExecutorTxRequired; var numJobsToAcquire = acquisitionStrategy.GetNumJobsToAcquire(currentProcessEngine.Name); AcquiredJobs acquiredJobs = null; if (numJobsToAcquire > 0) { JobExecutor.LogAcquisitionAttempt(currentProcessEngine); acquiredJobs = commandExecutor.Execute(JobExecutor.GetAcquireJobsCmd(numJobsToAcquire)); } else { acquiredJobs = new AcquiredJobs(numJobsToAcquire); } context.SubmitAcquiredJobs(currentProcessEngine.Name, acquiredJobs); JobExecutor.LogAcquiredJobs(currentProcessEngine, acquiredJobs.Size()); JobExecutor.LogAcquisitionFailureJobs(currentProcessEngine, acquiredJobs.NumberOfJobsFailedToLock); Log.AcquiredJobs(currentProcessEngine.Name, acquiredJobs); return(acquiredJobs); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <returns> true, if all acquired jobs (spanning all engines) were rejected for execution</returns> protected internal virtual bool AllSubmittedJobsRejected(JobAcquisitionContext context) { foreach (var acquiredJobsForEngine in context.AcquiredJobsByEngine) { var engineName = acquiredJobsForEngine.Key; var acquiredJobBatches = acquiredJobsForEngine.Value.JobIdBatches; var resubmittedJobBatches = context.AdditionalJobBatchesByEngine.GetValueOrNull(engineName); var rejectedJobBatches = context.RejectedJobBatchesByEngine.GetValueOrNull(engineName); var numJobsSubmittedForExecution = acquiredJobBatches.Count; if (resubmittedJobBatches != null) { numJobsSubmittedForExecution += resubmittedJobBatches.Count; } var numJobsRejected = 0; if (rejectedJobBatches != null) { numJobsRejected += rejectedJobBatches.Count; } // if not all jobs scheduled for execution have been rejected if ((numJobsRejected == 0) || numJobsSubmittedForExecution > numJobsRejected) { return(false); } } return(true); }
public virtual void Reconfigure(JobAcquisitionContext context) { ReconfigureIdleLevel(context); ReconfigureBackoffLevel(context); ReconfigureNumberOfJobsToAcquire(context); ExecutionSaturated = AllSubmittedJobsRejected(context); }
protected internal virtual void ReconfigureNumberOfJobsToAcquire(JobAcquisitionContext context) { // calculate the number of jobs to acquire next time JobsToAcquire.Clear(); foreach (var acquiredJobsEntry in context.AcquiredJobsByEngine) { var engineName = acquiredJobsEntry.Key; var numJobsToAcquire = (int)(BaseNumJobsToAcquire * Math.Pow(BackoffIncreaseFactor, BackoffLevel)); var rejectedJobBatchesForEngine = context.RejectedJobBatchesByEngine.GetValueOrNull(engineName); if (rejectedJobBatchesForEngine != null) { numJobsToAcquire -= rejectedJobBatchesForEngine.Count; } numJobsToAcquire = Math.Max(0, numJobsToAcquire); JobsToAcquire[engineName] = numJobsToAcquire; } }
protected internal virtual void ReconfigureIdleLevel(JobAcquisitionContext context) { if (context.JobAdded) { IdleLevel = 0; } else { if (context.AreAllEnginesIdle() || context.AcquisitionException != null) { if (IdleLevel < MaxIdleLevel) { IdleLevel++; } } else { IdleLevel = 0; } } }
protected internal virtual void ExecuteJobs(JobAcquisitionContext context, ProcessEngineImpl currentProcessEngine, AcquiredJobs acquiredJobs) { // submit those jobs that were acquired in previous cycles but could not be scheduled for execution var additionalJobs = context.AdditionalJobBatchesByEngine.GetValueOrNull(currentProcessEngine.Name); if (additionalJobs != null) { foreach (var jobBatch in additionalJobs) { Log.ExecuteJobs(currentProcessEngine.Name, jobBatch); JobExecutor.ExecuteJobs(jobBatch, currentProcessEngine); } } // submit those jobs that were acquired in the current cycle foreach (var jobIds in acquiredJobs.JobIdBatches) { Log.ExecuteJobs(currentProcessEngine.Name, jobIds); JobExecutor.ExecuteJobs(jobIds, currentProcessEngine); } }
protected internal virtual void ReconfigureBackoffLevel(JobAcquisitionContext context) { // if for any engine, jobs could not be locked due to optimistic locking, back off if (context.HasJobAcquisitionLockFailureOccurred()) { NumAcquisitionsWithoutLockingFailure = 0; ApplyJitter = true; if (BackoffLevel < MaxBackoffLevel) { BackoffLevel++; } } else { ApplyJitter = false; NumAcquisitionsWithoutLockingFailure++; if (NumAcquisitionsWithoutLockingFailure >= BackoffDecreaseThreshold && BackoffLevel > 0) { BackoffLevel--; NumAcquisitionsWithoutLockingFailure = 0; } } }
/// <summary> /// Reconfigure the acquisition strategy based on the current cycle's acquisition context. /// A strategy implementation may update internal data structure to calculate a different wait time /// before the next cycle of acquisition is performed. /// </summary> protected internal virtual void ConfigureNextAcquisitionCycle(JobAcquisitionContext acquisitionContext, IJobAcquisitionStrategy acquisitionStrategy) { acquisitionStrategy.Reconfigure(acquisitionContext); }
public SequentialJobAcquisitionRunnable(JobExecutor jobExecutor) : base(jobExecutor) { AcquisitionContext = InitializeAcquisitionContext(); }