Changeset 1102


Ignore:
Timestamp:
6/3/2009 3:55:56 AM (5 years ago)
Author:
lowjoel
Message:

A whole host of scheduler fixes:

  • When cancelling scheduled tasks we removed the scheduled version of the task as well so tasks will no longer run on the schedule
  • When editing tasks the schedules were not updated and scheduled tasks still ran on the old schedule
  • Determining whether the task was queued manually for execution was a little unpredictable, this is now fixed
  • For consistency, when tasks are queued we will prevent editing of tasks

And a few stylistic fixes

  • Do not catch general exception types
  • Use automatic properties where possible
  • Don't use multiple casts
Location:
trunk/eraser6
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser6/Eraser.Manager/DirectExecutor.cs

    r1085 r1102  
    4545        public DirectExecutor() 
    4646        { 
     47            TaskAdded += OnTaskAdded; 
     48            TaskDeleted += OnTaskDeleted; 
    4749            Tasks = new DirectExecutorTasksCollection(this); 
    4850            thread = new Thread(Main); 
     
    7173            lock (tasksLock) 
    7274            { 
    73                 //Set the task variable to indicate that the task is already 
    74                 //waiting to be executed. 
    75                 task.Queued = true; 
    76  
    7775                //Queue the task to be run immediately. 
    7876                DateTime executionTime = DateTime.Now; 
     
    117115                for (int i = 0; i != scheduledTasks.Count; ++i) 
    118116                    for (int j = 0; j < scheduledTasks.Values[i].Count; ++j) 
    119                         if (scheduledTasks.Values[i][j] == task) 
     117                    { 
     118                        Task currentTask = scheduledTasks.Values[i][j]; 
     119                        if (currentTask == task && 
     120                            (!(currentTask.Schedule is RecurringSchedule) || 
     121                                ((RecurringSchedule)currentTask.Schedule).NextRun != scheduledTasks.Keys[i])) 
    120122                        { 
    121123                            scheduledTasks.Values[i].RemoveAt(i); 
    122  
    123                             if (scheduledTasks.Values[i].Count == 0) 
    124                                 scheduledTasks.RemoveAt(i); 
    125                             break; 
    126124                        } 
     125                    } 
     126        } 
     127 
     128        internal override bool IsTaskQueued(Task task) 
     129        { 
     130            lock (tasksLock) 
     131                foreach (KeyValuePair<DateTime, List<Task>> tasks in scheduledTasks) 
     132                    foreach (Task i in tasks.Value) 
     133                        if (task == i) 
     134                            if (task.Schedule is RecurringSchedule) 
     135                            { 
     136                                if (((RecurringSchedule)task.Schedule).NextRun != tasks.Key) 
     137                                    return true; 
     138                            } 
     139                            else 
     140                                return true; 
     141 
     142            return false; 
     143        } 
     144 
     145        private void OnTaskAdded(object sender, TaskEventArgs e) 
     146        { 
     147            e.Task.TaskEdited += OnTaskEdited; 
     148        } 
     149 
     150        private void OnTaskEdited(object sender, TaskEventArgs e) 
     151        { 
     152            //Find all schedule entries containing the task - since the user cannot make 
     153            //edits to the task when it is queued (only if it is scheduled) remove 
     154            //all task references and add them back 
     155            lock (tasksLock) 
     156                for (int i = 0; i != scheduledTasks.Count; ++i) 
     157                    for (int j = 0; j < scheduledTasks.Values[i].Count; ) 
     158                    { 
     159                        Task currentTask = scheduledTasks.Values[i][j]; 
     160                        if (currentTask == e.Task) 
     161                            scheduledTasks.Values[i].RemoveAt(j); 
     162                        else 
     163                            j++; 
     164                    } 
     165 
     166            //Then reschedule the task 
     167            if (e.Task.Schedule is RecurringSchedule) 
     168                ScheduleTask(e.Task); 
     169        } 
     170 
     171        private void OnTaskDeleted(object sender, TaskEventArgs e) 
     172        { 
     173            e.Task.TaskEdited -= OnTaskEdited; 
    127174        } 
    128175 
     
    144191                lock (tasksLock) 
    145192                { 
    146                     if (scheduledTasks.Count != 0 && scheduledTasks.Values[0].Count != 0 && 
    147                         scheduledTasks.Keys[0] <= DateTime.Now) 
    148                     { 
    149                         List<Task> tasks = scheduledTasks.Values[0]; 
    150                         task = tasks[0]; 
    151                         tasks.RemoveAt(0); 
    152  
    153                         //Remove the entry from the sorted list if the list of tasks 
    154                         //with that one time to run has all been executed 
    155                         if (tasks.Count == 0) 
     193                    while (scheduledTasks.Count != 0) 
     194                        if (scheduledTasks.Values[0].Count == 0) 
     195                        { 
     196                            //Clean all all time slots at the start of the queue which are 
     197                            //empty 
    156198                            scheduledTasks.RemoveAt(0); 
    157                     } 
     199                        } 
     200                        else 
     201                        { 
     202                            if (scheduledTasks.Keys[0] <= DateTime.Now) 
     203                            { 
     204                                List<Task> tasks = scheduledTasks.Values[0]; 
     205                                task = tasks[0]; 
     206                                tasks.RemoveAt(0); 
     207                            } 
     208 
     209                            //Do schedule queue maintenance: clean up all empty timeslots 
     210                            if (task == null) 
     211                            { 
     212                                for (int i = 0; i < scheduledTasks.Count; ) 
     213                                    if (scheduledTasks.Values[i].Count == 0) 
     214                                        scheduledTasks.RemoveAt(i); 
     215                                    else 
     216                                        ++i; 
     217                            } 
     218 
     219                            break; 
     220                        } 
    158221                } 
    159222 
     
    170233 
    171234                        //Broadcast the task started event. 
    172                         task.Queued = false; 
    173235                        task.Canceled = false; 
    174236                        task.OnTaskStarted(new TaskEventArgs(task)); 
     
    186248                                progress.Event.CurrentTarget = target; 
    187249                                ++progress.Event.CurrentTargetIndex; 
    188                                 if (target is UnusedSpaceTarget) 
    189                                     EraseUnusedSpace(task, (UnusedSpaceTarget)target, progress); 
    190                                 else if (target is FileSystemObjectTarget) 
    191                                     EraseFilesystemObject(task, (FileSystemObjectTarget)target, progress); 
     250 
     251                                UnusedSpaceTarget unusedSpaceTarget = 
     252                                    target as UnusedSpaceTarget; 
     253                                FileSystemObjectTarget fileSystemObjectTarget = 
     254                                    target as FileSystemObjectTarget; 
     255 
     256                                if (unusedSpaceTarget != null) 
     257                                    EraseUnusedSpace(task, unusedSpaceTarget, progress); 
     258                                else if (fileSystemObjectTarget != null) 
     259                                    EraseFilesystemObject(task, fileSystemObjectTarget, progress); 
    192260                                else 
    193261                                    throw new ArgumentException(S._("Unknown erasure target.")); 
     
    695763                    EraseFileClusterTips(files[i], method); 
    696764                } 
    697                 catch (Exception e) 
     765                catch (IOException e) 
    698766                { 
    699767                    task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 
  • trunk/eraser6/Eraser.Manager/Executor.cs

    r1012 r1102  
    7171        /// Removes the given task from the execution queue. 
    7272        /// </summary> 
     73        /// <remarks>If the task given runs a recurring schedule, the task will only 
     74        /// remove requested tasks and not the scheduled ones</remarks> 
    7375        /// <param name="task">The task to cancel.</param> 
    7476        public abstract void UnqueueTask(Task task); 
     77 
     78        /// <summary> 
     79        /// Gets whether a task is currently queued for execution, outside of the 
     80        /// scheduled time. 
     81        /// </summary> 
     82        /// <param name="task">The task to query.</param> 
     83        /// <returns>True if the task is currently queued, false otherwise.</returns> 
     84        internal abstract bool IsTaskQueued(Task task); 
    7585 
    7686        /// <summary> 
  • trunk/eraser6/Eraser.Manager/RemoteExecutor.cs

    r1024 r1102  
    396396        } 
    397397 
     398        internal override bool IsTaskQueued(Task task) 
     399        { 
     400            throw new NotImplementedException(); 
     401        } 
     402 
    398403        public override ExecutorTasksCollection Tasks { get; protected set; } 
    399404 
  • trunk/eraser6/Eraser.Manager/Schedule.cs

    r957 r1102  
    9797 
    9898        /// <summary> 
     99        /// The owner of this schedule item. 
     100        /// </summary> 
     101        public Task Owner 
     102        { 
     103            get; 
     104            internal set; 
     105        } 
     106 
     107        /// <summary> 
    99108        /// Populates a SerializationInfo with the data needed to serialize the 
    100109        /// target object. 
     
    186195            monthlySchedule = (int)info.GetValue("MonthlySchedule", typeof(int)); 
    187196 
    188             lastRun = (DateTime)info.GetDateTime("LastRun"); 
    189             nextRun = (DateTime)info.GetDateTime("NextRun"); 
     197            LastRun = (DateTime)info.GetDateTime("LastRun"); 
     198            NextRunCache = (DateTime)info.GetDateTime("NextRun"); 
    190199        } 
    191200 
     
    198207            info.AddValue("WeeklySchedule", weeklySchedule); 
    199208            info.AddValue("MonthlySchedule", monthlySchedule); 
    200             info.AddValue("LastRun", lastRun); 
    201             info.AddValue("NextRun", nextRun); 
     209            info.AddValue("LastRun", LastRun); 
     210            info.AddValue("NextRun", NextRunCache); 
    202211        } 
    203212        #endregion 
     
    216225        { 
    217226            get { return type; } 
    218             set { type = value; } 
     227            set 
     228            { 
     229                type = value; 
     230                if (Owner != null) 
     231                    Owner.OnTaskEdited(); 
     232            } 
    219233        } 
    220234 
     
    241255 
    242256                frequency = value; 
     257                if (Owner != null) 
     258                    Owner.OnTaskEdited(); 
    243259            } 
    244260        } 
     
    250266        { 
    251267            get { return executionTime; } 
    252             set { executionTime = value; } 
     268            set 
     269            { 
     270                executionTime = value; 
     271                if (Owner != null) 
     272                    Owner.OnTaskEdited(); 
     273            } 
    253274        } 
    254275 
     
    275296 
    276297                weeklySchedule = value; 
     298                if (Owner != null) 
     299                    Owner.OnTaskEdited(); 
    277300            } 
    278301        } 
     
    292315                return monthlySchedule; 
    293316            } 
    294             set { monthlySchedule = value; } 
     317            set 
     318            { 
     319                monthlySchedule = value; 
     320 
     321                if (Owner != null) 
     322                    Owner.OnTaskEdited(); 
     323            } 
    295324        } 
    296325 
     
    301330        public DateTime LastRun 
    302331        { 
    303             get { return lastRun; } 
     332            get; 
     333            private set; 
    304334        } 
    305335 
     
    318348                if (nextRun == DateTime.MinValue) 
    319349                    nextRun = DateTime.Now; 
    320                 nextRun = nextRun.AddHours(executionTime.Hour - nextRun.Hour); 
    321                 nextRun = nextRun.AddMinutes(executionTime.Minute - nextRun.Minute); 
    322                 nextRun = nextRun.AddSeconds(executionTime.Second - nextRun.Second); 
     350                nextRun = new DateTime(nextRun.Year, nextRun.Month, nextRun.Day, executionTime.Hour, 
     351                    executionTime.Minute, executionTime.Second); 
    323352 
    324353                switch (ScheduleType) 
     
    339368                    { 
    340369                        while (nextRun < DateTime.Now || 
    341                             lastRun.DayOfWeek == DayOfWeek.Saturday || 
    342                             lastRun.DayOfWeek == DayOfWeek.Sunday) 
     370                            LastRun.DayOfWeek == DayOfWeek.Saturday || 
     371                            LastRun.DayOfWeek == DayOfWeek.Sunday) 
    343372                            nextRun = nextRun.AddDays(1); 
    344373                        break; 
     
    398427            get 
    399428            { 
    400                 return lastRun != DateTime.MinValue && NextRun != nextRun; 
     429                return LastRun != DateTime.MinValue && NextRun != NextRunCache; 
    401430            } 
    402431        } 
     
    422451        internal void Reschedule(DateTime lastRun) 
    423452        { 
    424             this.lastRun = lastRun; 
    425             nextRun = NextRun; 
     453            LastRun = lastRun; 
     454            NextRunCache = NextRun; 
    426455        } 
    427456 
     
    432461        private int monthlySchedule; 
    433462 
    434         private DateTime lastRun; 
    435         private DateTime nextRun; 
     463        /// <summary> 
     464        /// The next time the task is scheduled to run - this is cached from the previous 
     465        /// calculation of the next run time to determine if the task's schedule was missed 
     466        /// </summary> 
     467        private DateTime NextRunCache; 
    436468    } 
    437469 
  • trunk/eraser6/Eraser.Manager/Task.cs

    r1085 r1102  
    4747            Targets.Owner = this; 
    4848            Log = (Logger)info.GetValue("Log", typeof(Logger)); 
     49            Canceled = false; 
    4950 
    5051            Schedule schedule = (Schedule)info.GetValue("Schedule", typeof(Schedule)); 
     
    8081            Targets = new ErasureTargetsCollection(this); 
    8182            Schedule = Schedule.RunNow; 
     83            Canceled = false; 
    8284            Log = new Logger(); 
    8385        } 
     
    138140        /// executor is idle. 
    139141        /// </summary> 
    140         public bool Queued { get; internal set; } 
     142        public bool Queued 
     143        { 
     144            get 
     145            { 
     146                return Executor.IsTaskQueued(this); 
     147            } 
     148        } 
    141149 
    142150        /// <summary> 
     
    153161        /// The schedule for running the task. 
    154162        /// </summary> 
    155         public Schedule Schedule { get; set; } 
     163        public Schedule Schedule 
     164        { 
     165            get 
     166            { 
     167                return schedule; 
     168            } 
     169            set 
     170            { 
     171                if (schedule.Owner != null) 
     172                    throw new ArgumentException(S._("The schedule provided can only " + 
     173                        "belong to one task at a time")); 
     174 
     175                if (schedule is RecurringSchedule) 
     176                    ((RecurringSchedule)schedule).Owner = null; 
     177                schedule = value; 
     178                if (schedule is RecurringSchedule) 
     179                    ((RecurringSchedule)schedule).Owner = this; 
     180                OnTaskEdited(); 
     181            } 
     182        } 
    156183 
    157184        /// <summary> 
     
    160187        public Logger Log { get; private set; } 
    161188 
     189        private Schedule schedule; 
     190 
    162191        #region Events 
    163192        /// <summary> 
     193        /// The task has been edited. 
     194        /// </summary> 
     195        public EventHandler<TaskEventArgs> TaskEdited { get; set; } 
     196 
     197        /// <summary> 
    164198        /// The start of the execution of a task. 
    165199        /// </summary> 
     
    175209        /// </summary> 
    176210        public EventHandler<TaskEventArgs> TaskFinished { get; set; } 
     211 
     212        /// <summary> 
     213        /// Broadcasts the task edited event. 
     214        /// </summary> 
     215        internal void OnTaskEdited() 
     216        { 
     217            if (TaskEdited != null) 
     218                TaskEdited(this, new TaskEventArgs(this)); 
     219        } 
    177220 
    178221        /// <summary> 
     
    613656                        result.AddRange(GetFiles(dir)); 
    614657                    } 
    615                     catch (Exception e) 
     658                    catch (DirectoryNotFoundException e) 
    616659                    { 
    617660                        //Ignore, but log. 
     
    720763                foreach (FileSystemInfo fsInfo in info.GetFileSystemInfos()) 
    721764                { 
    722                     if (fsInfo is FileInfo) 
     765                    FileInfo fileInfo = fsInfo as FileInfo; 
     766                    if (fileInfo != null) 
    723767                    { 
    724                         totalSize += ((FileInfo)fsInfo).Length; 
    725                         GetPathADSes(paths, out totalSize, fsInfo.FullName); 
    726                         paths.Add(fsInfo.FullName); 
     768                        totalSize += fileInfo.Length; 
     769                        GetPathADSes(paths, out totalSize, fileInfo.FullName); 
     770                        paths.Add(fileInfo.FullName); 
    727771                    } 
    728772                    else 
  • trunk/eraser6/Eraser/SchedulerPanel.cs

    r1068 r1102  
    455455 
    456456            editTaskToolStripMenuItem.Enabled = scheduler.SelectedItems.Count == 1 && 
    457                 !((Task)scheduler.SelectedItems[0].Tag).Executing; 
     457                !((Task)scheduler.SelectedItems[0].Tag).Executing && 
     458                !((Task)scheduler.SelectedItems[0].Tag).Queued; 
    458459            deleteTaskToolStripMenuItem.Enabled = !aTaskExecuting; 
    459460        } 
     
    540541        private void editTaskToolStripMenuItem_Click(object sender, EventArgs e) 
    541542        { 
    542             if (scheduler.SelectedItems.Count != 1) 
    543                 return; 
     543            if (scheduler.SelectedItems.Count != 1 || 
     544                ((Task)scheduler.SelectedItems[0].Tag).Executing || 
     545                ((Task)scheduler.SelectedItems[0].Tag).Queued) 
     546            { 
     547                return; 
     548            } 
    544549 
    545550            //Make sure that the task is not being executed, or else. This can 
Note: See TracChangeset for help on using the changeset viewer.