/// <summary> /// Process the activities iteratively. /// </summary> public override void Run() { PacingInfo.OverallStartTime = DateTime.Now; PacingInfo.DurationLimit = new TimeSpan(0); PacingInfo.IterationLimit = _totalIterations; TraceFactory.Logger.Debug("Total Iterations: {0}".FormatWith(_totalIterations)); int runCount = 0; // Get the initial activity from the queue Activity currentActivity = null; do { if (!ExecutionHalted) { // Honor any pause request from the client, and stop right here if there is a pause. ApplicationFlowControl.Instance.CheckWait(LogActivityPaused, LogActivityResumed); DateTime activityStartTime = DateTime.Now; // Ensure that we have a valid activity if (currentActivity == null) { currentActivity = GetNextActivity(ref runCount); } // Now execute the current activity currentActivity.Execute(); TraceFactory.Logger.Debug("Completed activity {0} of {1}".FormatWith(runCount, _totalIterations)); // Go get the next activity var nextActivity = GetNextActivity(ref runCount); // Apply the appropriate Activity delay. It may be a Worker level delay or // it may be at the Activity level, and if at the Activity level, it may be // a delay every time the Activity executes, or it may be a delay only // after an Activity with an ExecutionCount > 1 completes. _delay.Apply(currentActivity, nextActivity); // mark end of activity (including any delay) PacingInfo.MarkActivityRunEnd(currentActivity, activityStartTime); // Set the current Activity to the next Activity and loop to the top. currentActivity = nextActivity; } else { break; } } while (runCount <= _totalIterations); }
/// <summary> /// Process activities for the set duration. /// </summary> /// <param name="duration">The duration.</param> /// <exception cref="WorkerHaltedException">Worker has been signaled to halt</exception> public void Run(TimeSpan duration) { PacingInfo.OverallStartTime = DateTime.Now; PacingInfo.DurationLimit = duration; PacingInfo.IterationLimit = -1; TraceFactory.Logger.Debug("Will run for {0} mins".FormatWith(duration.TotalMinutes)); // Start the monitor which will add up all pause time that may occur during execution _monitor.Start(); int loopCount = 0; var startTime = DateTime.Now; TimeSpan totalRunTime = TimeSpan.Zero; TimeSpan totalDuration = TimeSpan.Zero; // Get the initial activity from the queue var currentActivity = GetNextActivity(ref loopCount); do { if (!ExecutionHalted) { // This will adjust the expiration time based on how long it sits in a paused state. ApplicationFlowControl.Instance.CheckWait(); DateTime activityStartTime = DateTime.Now; // Run the next activity currentActivity.Execute(); PacingInfo.MarkActivityRunEnd(currentActivity, activityStartTime); // Calculate the remaining time in this run by subtracting the total time the engine has // been running from the duration plus the pause time. All pause time is used to shift // the total duration as pause time should not impact the overall duration. totalRunTime = DateTime.Now - startTime; totalDuration = duration + _monitor.PauseTime; var remainingTime = totalDuration - totalRunTime; //TraceFactory.Logger.Debug("RUN: {0} DUR: {1} REM: {2}".FormatWith(totalRunTime.TotalSeconds, totalDuration.TotalSeconds, remainingTime.TotalSeconds)); // Go get the next activity var nextActivity = GetNextActivity(ref loopCount); // Apply the appropriate Activity delay. It may be a Worker level delay or // it may be at the Activity level, and if at the Activity level, it may be // a delay every time the Activity executes, or it may be a delay only // after an Activity with an ExecutionCount > 1 completes. _delay.Apply(currentActivity, nextActivity); // Set the current Activity to the next Activity and loop to the top. currentActivity = nextActivity; var endTime = startTime.Add(duration + _monitor.PauseTime).ToLongTimeString(); TraceFactory.Logger.Debug("Run Complete. Completed: {0}. Run to {1}".FormatWith(loopCount++, endTime)); } else { throw new WorkerHaltedException("Worker has been signaled to halt"); } // Run until the total run time is less than the defined duration plus any pause time. totalRunTime = DateTime.Now - startTime; totalDuration = duration + _monitor.PauseTime; TraceFactory.Logger.Debug("RUN: {0} DUR: {1}".FormatWith(totalRunTime.TotalSeconds, totalDuration.TotalSeconds)); } while (totalRunTime < totalDuration); TraceFactory.Logger.Debug("Finished"); }
public void Run(TimeSpan duration) { PacingInfo.OverallStartTime = DateTime.Now; PacingInfo.DurationLimit = duration; PacingInfo.IterationLimit = -1; TraceFactory.Logger.Debug("Will run for {0} mins".FormatWith(duration.TotalMinutes)); // Start the monitor which will add up all pause time that may occur during execution int loopCount = 0; var startTime = DateTime.Now; TimeSpan totalRunTime = TimeSpan.Zero; TimeSpan totalDuration = duration; // Get the initial activity from the queue var currentActivity = GetNextActivity(ref loopCount); do { // Execute the Activity DateTime activityStartTime = DateTime.Now; currentActivity.Execute(); PacingInfo.MarkActivityRunEnd(currentActivity, activityStartTime); DateTime activityEndTime = DateTime.Now; // Calculate the remaining time in this run by subtracting the total time the engine has // been running. totalRunTime = DateTime.Now - startTime; var remainingTime = totalDuration - totalRunTime; // Go get the next activity var nextActivity = GetNextActivity(ref loopCount); // If the start time + _pace time is passed, go to the next activity in the queue // Apply a delay if the endtime is less than start + _pace to hit the next start + _pace time point to start the next activity var timeAndPace = activityStartTime + _pace; if (activityEndTime < timeAndPace) { Delay.Wait(timeAndPace - activityEndTime); } else { while (activityEndTime > timeAndPace) { timeAndPace = timeAndPace + _pace; } Delay.Wait(timeAndPace - activityEndTime); } // Set the current Activity to the next Activity and loop to the top. currentActivity = nextActivity; //var endTime = startTime.Add(duration).ToLongTimeString(); //TraceFactory.Logger.Debug("Run Complete. Completed: {0}. Run to {1}".FormatWith(loopCount++, endTime)); // Run until the total run time is less than the defined duration plus any pause time. } while (totalRunTime < totalDuration); TraceFactory.Logger.Debug("Finished"); }
public override void Run() { PacingInfo.OverallStartTime = DateTime.Now; PacingInfo.DurationLimit = TimeSpan.FromMinutes(_duration); PacingInfo.IterationLimit = _repeatCount * _activityCount; var totalActivities = PacingInfo.IterationLimit; var totalDuration = PacingInfo.DurationLimit.Ticks; TraceFactory.Logger.Debug("Duration: {0} mins, Iterations: {1}".FormatWith(PacingInfo.DurationLimit, PacingInfo.IterationLimit)); int activitiesExecuted = 0; do { // Check to make sure the user hasn't requested this worker to pause ApplicationFlowControl.Instance.CheckWait(LogActivityPaused, LogActivityResumed); // Record the start time, execute the activity and then record the end time. DateTime activityStartTime = DateTime.Now; // Execute the activity var activity = GetNextActivity(ref activitiesExecuted); activity.Execute(); PacingInfo.MarkActivityRunEnd(activity, activityStartTime); // Reset the pacing run count to the "official" pacing count determined by _pacingInfo activitiesExecuted = PacingInfo.PacingRunCount; // Get the remaining number of activities and the remaining time left in the run. int remainingActivities = totalActivities - activitiesExecuted; long remainingTime = totalDuration - PacingInfo.GetTotalElapsedTime().Ticks; // Get the percentage of activities and time remaining double percentActivitiesLeft = (double)remainingActivities / totalActivities; double percentTimeLeft = (double)remainingTime / totalDuration; // If we have not executed the entire activity set once, we don't have enough timing data to // determine a reasonable delay time. if (activitiesExecuted < _activityCount) { TraceFactory.Logger.Debug("Initial iteration, moving on immediately."); //Total duration / total activities will give us an even split of time for each activity for the first run. long timeAveragePerActivity = totalDuration / totalActivities; long currentTimeTaken = PacingInfo.GetTotalElapsedTime().Ticks; long allotedTimeAtCurrentActivity = timeAveragePerActivity * activitiesExecuted; long timeDifferentialBetweenAllotedAndCurrentTime = allotedTimeAtCurrentActivity - currentTimeTaken; //if time differential is positive, we haven't used up our buffer time, we can set a delay for the difference. //if it's negative, we're over our buffer time and need to catch up ASAP. if (timeDifferentialBetweenAllotedAndCurrentTime > 0) { Delay.Wait(new TimeSpan(timeDifferentialBetweenAllotedAndCurrentTime)); } else { TraceFactory.Logger.Debug("Iteration 1 behind target, moving on immediately"); } } else if (percentActivitiesLeft > percentTimeLeft) { // We are behind our target - execute the next activity immediately TraceFactory.Logger.Debug("Behind target, moving on immediately."); } else { // Get the number of activity "sets" (set of activities) remaining, this is a decimal number // meaning it includes partial set values. double remainingActivitySetCount = (double)remainingActivities / _activityCount; // Determine the amount of time we expect to use executing the remainder of the activities. // This is found by multiplying the average set execution time by the number of remaining sets. long remainingWorkingTime = (long)(PacingInfo.GetAverageExecutionTimeForSet() * remainingActivitySetCount); // Estimate the number of ticks available for pacing delays, calculated by removing the elapsed time // from the duration, and also removing all the times estimated to run the remaining activity sets. long remainingDelayTime = remainingTime - remainingWorkingTime; // The remaining number of times there should be a pacing delay applied. int remainingDelayCount = remainingActivities + 1; // We must not be on the last delay, and we must have available pacing delay ticks // in order to delay. If either of these are false, then we move on with no delay. if (remainingDelayCount > 1 && remainingDelayTime > 0) { TimeSpan pacingDelay = TimeSpan.FromTicks(remainingDelayTime / remainingDelayCount); TraceFactory.Logger.Debug("delay Secs: {0}".FormatWith(pacingDelay.TotalSeconds)); PacingInfo.RecordDelay(pacingDelay); Delay.Wait(pacingDelay); } else { TraceFactory.Logger.Debug("No delay, moving on immediately."); } } } while (PacingInfo.PacingRunCount < PacingInfo.IterationLimit && DateTime.Now.Subtract(PacingInfo.OverallStartTime) < PacingInfo.DurationLimit && !ExecutionHalted); }