/// <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);
        }
Esempio n. 2
0
        /// <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");
        }
Esempio n. 4
0
        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);
        }