Changeset 2487


Ignore:
Timestamp:
3/13/2012 11:37:30 PM (2 years ago)
Author:
lowjoel
Message:
  • Move the task execution machinery to the Task object, so that Tasks can execute independently of an Executor. The Executor instance now just manages task lists and schedules when tasks are supposed to run.
  • Report progress updates by pushing information to the SteppedProgressManager? instance associated with each erasure target. Furthermore, do not manipulate the state of the Task object, instead, let the Task object manage its own Progress state.
Location:
branches/eraser6/pluginsRewrite
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/pluginsRewrite/Eraser.Manager/DirectExecutor.cs

    r2470 r2487  
    254254                if (task != null) 
    255255                { 
     256                    LogSink sessionLog = new LogSink(); 
     257                    task.Log.Add(sessionLog); 
     258 
    256259                    //Start a new log session to separate this session's events 
    257260                    //from previous ones. 
    258                     LogSink sessionLog = new LogSink(); 
    259                     task.Log.Add(sessionLog); 
    260                     using (new LogSession(sessionLog)) 
     261                    try 
    261262                    { 
    262                         ExecuteTask(task); 
     263                        using (new LogSession(sessionLog)) 
     264                        { 
     265                            //Set the currently executing task. 
     266                            currentTask = task; 
     267 
     268                            //Prevent the system from sleeping. 
     269                            Power.ExecutionState = ExecutionState.Continuous | 
     270                                ExecutionState.SystemRequired; 
     271 
     272                            task.Execute(); 
     273                        } 
     274                    } 
     275                    finally 
     276                    { 
     277                        //Allow the system to sleep again. 
     278                        Power.ExecutionState = ExecutionState.Continuous; 
     279 
     280                        //If the task is a recurring task, reschedule it for the next execution 
     281                        //time since we are done with this one. 
     282                        if (task.Schedule is RecurringSchedule) 
     283                            ScheduleTask(task); 
     284 
     285                        //Remove the actively executing task from our instance variable 
     286                        currentTask = null; 
    263287                    } 
    264288                } 
     
    266290                //Wait for half a minute to check for the next scheduled task. 
    267291                schedulerInterrupt.WaitOne(30000, false); 
    268             } 
    269         } 
    270  
    271         /// <summary> 
    272         /// Executes the given task. 
    273         /// </summary> 
    274         /// <param name="task">The task to execute.</param> 
    275         private void ExecuteTask(Task task) 
    276         { 
    277             //Set the currently executing task. 
    278             currentTask = task; 
    279  
    280             //Prevent the system from sleeping. 
    281             Power.ExecutionState = ExecutionState.Continuous | ExecutionState.SystemRequired; 
    282  
    283             try 
    284             { 
    285                 //Broadcast the task started event. 
    286                 task.Canceled = false; 
    287                 task.OnTaskStarted(); 
    288  
    289                 //Run the task 
    290                 foreach (IErasureTarget target in task.Targets) 
    291                     try 
    292                     { 
    293                         target.Execute(); 
    294                     } 
    295                     catch (FatalException) 
    296                     { 
    297                         throw; 
    298                     } 
    299                     catch (OperationCanceledException) 
    300                     { 
    301                         throw; 
    302                     } 
    303                     catch (SharingViolationException) 
    304                     { 
    305                     } 
    306             } 
    307             catch (FatalException e) 
    308             { 
    309                 Logger.Log(e.Message, LogLevel.Fatal); 
    310             } 
    311             catch (OperationCanceledException e) 
    312             { 
    313                 Logger.Log(e.Message, LogLevel.Fatal); 
    314             } 
    315             catch (SharingViolationException) 
    316             { 
    317             } 
    318             finally 
    319             { 
    320                 //Allow the system to sleep again. 
    321                 Power.ExecutionState = ExecutionState.Continuous; 
    322  
    323                 //If the task is a recurring task, reschedule it since we are done. 
    324                 if (task.Schedule is RecurringSchedule) 
    325                 { 
    326                     ((RecurringSchedule)task.Schedule).Reschedule(DateTime.Now); 
    327                     ScheduleTask(task); 
    328                 } 
    329  
    330                 //And the task finished event. 
    331                 task.OnTaskFinished(); 
    332  
    333                 //If the task is an execute on restart task or run immediately task, it is 
    334                 //only run once and can now be restored to a manually run task 
    335                 if (task.Schedule == Schedule.RunOnRestart || task.Schedule == Schedule.RunNow) 
    336                     task.Schedule = Schedule.RunManually; 
    337  
    338                 //Remove the actively executing task from our instance variable 
    339                 currentTask = null; 
    340292            } 
    341293        } 
  • branches/eraser6/pluginsRewrite/Eraser.Manager/Task.cs

    r2485 r2487  
    4141    public class Task : ITask, ISerializable 
    4242    { 
     43        #region ErasureTargetProgressManagerStep 
     44        /// <summary> 
     45        /// Returns the progress of an erasure target, since that comprises the 
     46        /// steps of the Task Progress. 
     47        /// </summary> 
     48        private class ErasureTargetProgressManagerStep : SteppedProgressManagerStepBase 
     49        { 
     50            /// <summary> 
     51            /// Constructor. 
     52            /// </summary> 
     53            /// <param name="target">The erasure target represented by this object.</param> 
     54            /// <param name="steps">The number of targets in the task.</param> 
     55            public ErasureTargetProgressManagerStep(IErasureTarget target, int targets) 
     56                : base(1.0f / targets) 
     57            { 
     58                Target = target; 
     59            } 
     60 
     61            public override ProgressManagerBase Progress 
     62            { 
     63                get 
     64                { 
     65                    return Target.Progress; 
     66                } 
     67                set 
     68                { 
     69                    throw new InvalidOperationException(); 
     70                } 
     71            } 
     72 
     73            private IErasureTarget Target; 
     74        } 
     75        #endregion 
     76 
    4377        #region Serialization code 
    4478        protected Task(SerializationInfo info, StreamingContext context) 
     
    88122 
    89123        /// <summary> 
    90         /// Cancels the task from running, or, if the task is queued for running, 
    91         /// removes the task from the queue. 
    92         /// </summary> 
    93         public void Cancel() 
    94         { 
    95             Executor.UnqueueTask(this); 
    96             Canceled = true; 
    97         } 
    98  
    99         /// <summary> 
    100124        /// The Executor object which is managing this task. 
    101125        /// </summary> 
     
    152176                return S._("{0} and {1} other targets", result, Targets.Count - 3); 
    153177            } 
    154         } 
    155  
    156         /// <summary> 
    157         /// Gets the status of the task - whether it is being executed. 
    158         /// </summary> 
    159         public bool Executing { get; private set; } 
    160  
    161         /// <summary> 
    162         /// Gets whether this task is currently queued to run. This is true only 
    163         /// if the queue it is in is an explicit request, i.e will run when the 
    164         /// executor is idle. 
    165         /// </summary> 
    166         public bool Queued 
    167         { 
    168             get 
    169             { 
    170                 return Executor.IsTaskQueued(this); 
    171             } 
    172         } 
    173  
    174         /// <summary> 
    175         /// Gets whether the task has been cancelled from execution. 
    176         /// </summary> 
    177         public bool Canceled 
    178         { 
    179             get; 
    180             internal set; 
    181178        } 
    182179 
     
    242239        } 
    243240 
     241        /// <summary> 
     242        /// Gets the status of the task - whether it is being executed. 
     243        /// </summary> 
     244        public bool Executing { get; private set; } 
     245 
     246        /// <summary> 
     247        /// Gets whether this task is currently queued to run. This is true only 
     248        /// if the queue it is in is an explicit request, i.e will run when the 
     249        /// executor is idle. 
     250        /// </summary> 
     251        public bool Queued 
     252        { 
     253            get 
     254            { 
     255                if (Executor == null) 
     256                    throw new InvalidOperationException(); 
     257 
     258                return Executor.IsTaskQueued(this); 
     259            } 
     260        } 
     261 
     262        /// <summary> 
     263        /// Gets whether the task has been cancelled from execution. 
     264        /// </summary> 
     265        public bool Canceled 
     266        { 
     267            get; 
     268            private set; 
     269        } 
     270 
     271        /// <summary> 
     272        /// Cancels the task from running, or, if the task is queued for running, 
     273        /// removes the task from the queue. 
     274        /// </summary> 
     275        public void Cancel() 
     276        { 
     277            Executor.UnqueueTask(this); 
     278            Canceled = true; 
     279        } 
     280 
     281        /// <summary> 
     282        /// Executes the task in the context of the calling thread. 
     283        /// </summary> 
     284        public void Execute() 
     285        { 
     286            OnTaskStarted(); 
     287            Executing = true; 
     288            Canceled = false; 
     289            Progress = new SteppedProgressManager(); 
     290 
     291            try 
     292            { 
     293                //Run the task 
     294                foreach (IErasureTarget target in Targets) 
     295                    try 
     296                    { 
     297                        Progress.Steps.Add(new ErasureTargetProgressManagerStep( 
     298                            target, Targets.Count)); 
     299                        target.Execute(); 
     300                    } 
     301                    catch (FatalException) 
     302                    { 
     303                        throw; 
     304                    } 
     305                    catch (OperationCanceledException) 
     306                    { 
     307                        throw; 
     308                    } 
     309                    catch (SharingViolationException) 
     310                    { 
     311                    } 
     312            } 
     313            catch (FatalException e) 
     314            { 
     315                Logger.Log(e.Message, LogLevel.Fatal); 
     316            } 
     317            catch (OperationCanceledException e) 
     318            { 
     319                Logger.Log(e.Message, LogLevel.Fatal); 
     320            } 
     321            catch (SharingViolationException) 
     322            { 
     323            } 
     324            finally 
     325            { 
     326                //If the task is a recurring task, reschedule it since we are done. 
     327                if (Schedule is RecurringSchedule) 
     328                { 
     329                    ((RecurringSchedule)Schedule).Reschedule(DateTime.Now); 
     330                } 
     331 
     332                //If the task is an execute on restart task or run immediately task, it is 
     333                //only run once and can now be restored to a manually run task 
     334                if (Schedule == Schedule.RunOnRestart || Schedule == Schedule.RunNow) 
     335                    Schedule = Schedule.RunManually; 
     336 
     337                Progress = null; 
     338                Executing = false; 
     339                OnTaskFinished(); 
     340            } 
     341        } 
     342 
    244343        private Executor executor; 
    245344        private Schedule schedule; 
     
    274373        /// Broadcasts the task execution start event. 
    275374        /// </summary> 
    276         internal void OnTaskStarted() 
     375        private void OnTaskStarted() 
    277376        { 
    278377            if (TaskStarted != null) 
    279378                TaskStarted(this, EventArgs.Empty); 
    280             Executing = true; 
    281             Progress = new SteppedProgressManager(); 
    282379        } 
    283380 
     
    285382        /// Broadcasts the task execution completion event. 
    286383        /// </summary> 
    287         internal void OnTaskFinished() 
    288         { 
    289             Progress = null; 
    290             Executing = false; 
     384        private void OnTaskFinished() 
     385        { 
    291386            if (TaskFinished != null) 
    292387                TaskFinished(this, EventArgs.Empty); 
  • branches/eraser6/pluginsRewrite/Eraser.Plugins/ProgressManager.cs

    r2486 r2487  
    351351        /// The class which manages the steps which comprise the overall progress. 
    352352        /// </summary> 
    353         private class StepsList : IList<SteppedProgressManagerStep> 
     353        private class StepsList : IList<SteppedProgressManagerStepBase> 
    354354        { 
    355355            public StepsList(SteppedProgressManager manager) 
    356356            { 
    357                 List = new List<SteppedProgressManagerStep>(); 
     357                List = new List<SteppedProgressManagerStepBase>(); 
    358358                ListLock = manager.ListLock; 
    359359            } 
     
    361361            #region IList<SteppedProgressManagerStep> Members 
    362362 
    363             public int IndexOf(SteppedProgressManagerStep item) 
     363            public int IndexOf(SteppedProgressManagerStepBase item) 
    364364            { 
    365365                lock (ListLock) 
     
    367367            } 
    368368 
    369             public void Insert(int index, SteppedProgressManagerStep item) 
     369            public void Insert(int index, SteppedProgressManagerStepBase item) 
    370370            { 
    371371                lock (ListLock) 
     
    385385            } 
    386386 
    387             public SteppedProgressManagerStep this[int index] 
     387            public SteppedProgressManagerStepBase this[int index] 
    388388            { 
    389389                get 
     
    407407            #region ICollection<SteppedProgressManagerStep> Members 
    408408 
    409             public void Add(SteppedProgressManagerStep item) 
     409            public void Add(SteppedProgressManagerStepBase item) 
    410410            { 
    411411                lock (ListLock) 
     
    425425            } 
    426426 
    427             public bool Contains(SteppedProgressManagerStep item) 
     427            public bool Contains(SteppedProgressManagerStepBase item) 
    428428            { 
    429429                lock (ListLock) 
     
    431431            } 
    432432 
    433             public void CopyTo(SteppedProgressManagerStep[] array, int arrayIndex) 
     433            public void CopyTo(SteppedProgressManagerStepBase[] array, int arrayIndex) 
    434434            { 
    435435                lock (ListLock) 
     
    451451            } 
    452452 
    453             public bool Remove(SteppedProgressManagerStep item) 
     453            public bool Remove(SteppedProgressManagerStepBase item) 
    454454            { 
    455455                int index = List.IndexOf(item); 
     
    464464            #region IEnumerable<SteppedProgressManagerStep> Members 
    465465 
    466             public IEnumerator<SteppedProgressManagerStep> GetEnumerator() 
     466            public IEnumerator<SteppedProgressManagerStepBase> GetEnumerator() 
    467467            { 
    468468                return List.GetEnumerator(); 
     
    502502            /// The list storing the steps for this instance. 
    503503            /// </summary> 
    504             private List<SteppedProgressManagerStep> List; 
     504            private List<SteppedProgressManagerStepBase> List; 
    505505 
    506506            /// <summary> 
     
    621621        /// The list of steps involved in completion of the task. 
    622622        /// </summary> 
    623         public IList<SteppedProgressManagerStep> Steps 
     623        public IList<SteppedProgressManagerStepBase> Steps 
    624624        { 
    625625            get; 
     
    631631        /// no steps are executing (also when the task is complete) 
    632632        /// </summary> 
    633         public SteppedProgressManagerStep CurrentStep 
     633        public SteppedProgressManagerStepBase CurrentStep 
    634634        { 
    635635            get 
     
    640640                        return null; 
    641641 
    642                     foreach (SteppedProgressManagerStep step in Steps) 
     642                    foreach (SteppedProgressManagerStepBase step in Steps) 
    643643                        if (step.Progress.Progress < 1.0f) 
    644644                            return step; 
     
    680680    /// Represents one step in the list of steps to complete. 
    681681    /// </summary> 
    682     public class SteppedProgressManagerStep 
     682    public abstract class SteppedProgressManagerStepBase 
     683    { 
     684        /// <summary> 
     685        /// Constructor. 
     686        /// </summary> 
     687        /// <param name="weight">The weight of this step. The weight is a decimal 
     688        /// number in the range [0.0, 1.0] which represents the percentage of the 
     689        /// entire process this particular step is.</param> 
     690        protected SteppedProgressManagerStepBase(float weight) 
     691            : this(weight, null) 
     692        { 
     693        } 
     694 
     695        /// <summary> 
     696        /// Constructor. 
     697        /// </summary> 
     698        /// <param name="weight">The weight of this step. The weight is a decimal 
     699        /// number in the range [0.0, 1.0] which represents the percentage of the 
     700        /// entire process this particular step is.</param> 
     701        /// <param name="name">A user-specified value of the name of this step. 
     702        /// This value is not used by the class at all.</param> 
     703        protected SteppedProgressManagerStepBase(float weight, string name) 
     704        { 
     705            if (float.IsInfinity(weight) || float.IsNaN(weight)) 
     706                throw new ArgumentException("The weight of a progress manager step must be " + 
     707                    "a valid floating-point value."); 
     708 
     709            Weight = weight; 
     710            Name = name; 
     711        } 
     712 
     713        /// <summary> 
     714        /// The <see cref="ProgressManagerBase"/> instance which measures the 
     715        /// progress of the step. 
     716        /// </summary> 
     717        public abstract ProgressManagerBase Progress 
     718        { 
     719            get; 
     720            set; 
     721        } 
     722 
     723        /// <summary> 
     724        /// The weight associated with this step. 
     725        /// </summary> 
     726        public float Weight 
     727        { 
     728            get; 
     729            private set; 
     730        } 
     731 
     732        /// <summary> 
     733        /// The name of this step. 
     734        /// </summary> 
     735        public string Name 
     736        { 
     737            get; 
     738            set; 
     739        } 
     740    } 
     741 
     742    public class SteppedProgressManagerStep : SteppedProgressManagerStepBase 
    683743    { 
    684744        /// <summary> 
     
    706766        /// This value is not used by the class at all.</param> 
    707767        public SteppedProgressManagerStep(ProgressManagerBase progress, float weight, string name) 
    708         { 
    709             if (float.IsInfinity(weight) || float.IsNaN(weight)) 
    710                 throw new ArgumentException("The weight of a progress manager step must be " + 
    711                     "a valid floating-point value."); 
    712  
     768            : base(weight, name) 
     769        { 
    713770            Progress = progress; 
    714             Weight = weight; 
    715             Name = name; 
    716771        } 
    717772 
     
    720775        /// progress of the step. 
    721776        /// </summary> 
    722         public ProgressManagerBase Progress 
    723         { 
    724             get; 
    725             set; 
    726         } 
    727  
    728         /// <summary> 
    729         /// The weight associated with this step. 
    730         /// </summary> 
    731         public float Weight 
    732         { 
    733             get; 
    734             private set; 
    735         } 
    736  
    737         /// <summary> 
    738         /// The name of this step. 
    739         /// </summary> 
    740         public string Name 
     777        public override ProgressManagerBase Progress 
    741778        { 
    742779            get; 
Note: See TracChangeset for help on using the changeset viewer.