Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveJobs/HiveTask.cs @ 7191

Last change on this file since 7191 was 7191, checked in by ascheibe, 12 years ago

#1709

  • tooltip now shows the name and the id of a task
  • the date is now shown on the x-axis for runs spanning multiple days
File size: 19.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using System.Threading;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Clients.Hive {
35
36  [Item("Hive Task", "Represents a hive task.")]
37  [StorableClass]
38  public class HiveTask : NamedItem, IItemTree<HiveTask> {
39    protected static object locker = new object();
40    protected ReaderWriterLockSlim childHiveTasksLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
41
42    public override Image ItemImage {
43      get {
44        if (task.Id == Guid.Empty) { // not yet uploaded
45          return HeuristicLab.Common.Resources.VSImageLibrary.Event;
46        } else {
47          if (task.State == TaskState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
48          else if (task.State == TaskState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
49          else if (task.State == TaskState.Transferring) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
50          else if (task.State == TaskState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
51          else if (task.State == TaskState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
52          else if (task.State == TaskState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
53          else if (task.State == TaskState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
54          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
55        }
56      }
57    }
58
59    [Storable]
60    protected Task task;
61    public Task Task {
62      get { return task; }
63      set {
64        if (task != value) {
65          DeregisterJobEvents();
66          task = value;
67          RegisterJobEvents();
68          IsFinishedTaskDownloaded = false;
69          OnTaskChanged();
70          OnToStringChanged();
71          OnItemImageChanged();
72        }
73
74      }
75    }
76
77    [Storable]
78    protected ItemTask itemTask;
79    public ItemTask ItemTask {
80      get { return itemTask; }
81      set {
82        if (itemTask != null && syncTasksWithOptimizers) {
83          this.childHiveTasks.Clear();
84        }
85        if (itemTask != value) {
86          DergisterItemTaskEvents();
87          itemTask = value;
88          RegisterItemTaskEvents();
89          OnItemTaskChanged();
90          IsFinishedTaskDownloaded = true;
91        }
92      }
93    }
94
95    // task downloaded since last status change
96    [Storable]
97    private bool isFinishedTaskDownloaded = false;
98    public bool IsFinishedTaskDownloaded {
99      get { return isFinishedTaskDownloaded; }
100      set {
101        if (value != isFinishedTaskDownloaded) {
102          this.isFinishedTaskDownloaded = value;
103          OnIsFinishedJobDownloadedChanged();
104        }
105      }
106    }
107
108    public bool IsDownloading { get; set; }
109
110    // if true, all control buttons should be enabled. otherwise disabled
111    private bool isControllable = true;
112    public bool IsControllable {
113      get { return isControllable; }
114      set {
115        if (value != isControllable) {
116          isControllable = value;
117          OnIsControllableChanged();
118          childHiveTasksLock.EnterReadLock();
119          try {
120            foreach (var hiveJob in childHiveTasks) {
121              hiveJob.IsControllable = value;
122            }
123          } finally {
124            childHiveTasksLock.ExitReadLock();
125          }
126        }
127      }
128    }
129
130    [Storable]
131    protected ItemList<HiveTask> childHiveTasks;
132    public virtual ReadOnlyItemList<HiveTask> ChildHiveTasks {
133      get {
134        childHiveTasksLock.EnterReadLock();
135        try {
136          return childHiveTasks.AsReadOnly();
137        } finally { childHiveTasksLock.ExitReadLock(); }
138      }
139    }
140
141    [Storable]
142    protected bool syncTasksWithOptimizers = true;
143
144    public StateLogList StateLog {
145      get {
146        var list = new StateLogList(this.task.StateLog);
147        list.ForEach(s => { s.TaskName = itemTask.Name; });
148        return list;
149      }
150    }
151
152    public StateLogListList ChildStateLogList {
153      get { return new StateLogListList(this.childHiveTasks.Select(x => x.StateLog)); }
154    }
155
156    #region Constructors and Cloning
157    [StorableConstructor]
158    protected HiveTask(bool deserializing) { }
159
160    public HiveTask() {
161      this.Task = new Task() { CoresNeeded = 1, MemoryNeeded = 0 };
162      task.State = TaskState.Offline;
163      this.childHiveTasks = new ItemList<HiveTask>();
164      syncTasksWithOptimizers = true;
165      RegisterChildHiveJobEvents();
166    }
167
168    public HiveTask(ItemTask itemJob, bool autoCreateChildHiveJobs)
169      : this() {
170      this.syncTasksWithOptimizers = autoCreateChildHiveJobs;
171      this.ItemTask = itemJob;
172      this.syncTasksWithOptimizers = true;
173    }
174
175    public HiveTask(Task job, TaskData taskData, bool autoCreateChildHiveTasks) {
176      this.syncTasksWithOptimizers = autoCreateChildHiveTasks;
177      this.Task = job;
178      try {
179        this.ItemTask = PersistenceUtil.Deserialize<ItemTask>(taskData.Data);
180      }
181      catch {
182        this.ItemTask = null;
183      }
184      this.childHiveTasks = new ItemList<HiveTask>();
185      this.syncTasksWithOptimizers = true;
186      RegisterChildHiveJobEvents();
187    }
188
189    protected HiveTask(HiveTask original, Cloner cloner)
190      : base(original, cloner) {
191      this.Task = cloner.Clone(original.task);
192      this.ItemTask = cloner.Clone(original.ItemTask);
193      original.childHiveTasksLock.EnterReadLock();
194      try {
195        this.childHiveTasks = cloner.Clone(original.childHiveTasks);
196      } finally { original.childHiveTasksLock.ExitReadLock(); }
197      this.syncTasksWithOptimizers = original.syncTasksWithOptimizers;
198      this.isFinishedTaskDownloaded = original.isFinishedTaskDownloaded;
199    }
200    public override IDeepCloneable Clone(Cloner cloner) {
201      return new HiveTask(this, cloner);
202    }
203    #endregion
204
205    protected virtual void UpdateChildHiveTasks() { }
206
207    protected virtual void RegisterItemTaskEvents() {
208      if (ItemTask != null) {
209        ItemTask.ComputeInParallelChanged += new EventHandler(ItemJob_ComputeInParallelChanged);
210        ItemTask.ToStringChanged += new EventHandler(ItemJob_ToStringChanged);
211      }
212    }
213    protected virtual void DergisterItemTaskEvents() {
214      if (ItemTask != null) {
215        ItemTask.ComputeInParallelChanged -= new EventHandler(ItemJob_ComputeInParallelChanged);
216        ItemTask.ToStringChanged -= new EventHandler(ItemJob_ToStringChanged);
217      }
218    }
219
220    protected virtual void RegisterChildHiveJobEvents() {
221      this.childHiveTasks.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsAdded);
222      this.childHiveTasks.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsRemoved);
223      this.childHiveTasks.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnCollectionReset);
224    }
225    protected virtual void DeregisterChildHiveJobEvents() {
226      this.childHiveTasks.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsAdded);
227      this.childHiveTasks.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsRemoved);
228      this.childHiveTasks.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnCollectionReset);
229    }
230
231    protected virtual void ItemJob_ToStringChanged(object sender, EventArgs e) {
232      this.OnToStringChanged();
233    }
234
235    protected virtual void ItemJob_ComputeInParallelChanged(object sender, EventArgs e) {
236      if (ItemTask != null && syncTasksWithOptimizers) {
237        this.UpdateChildHiveTasks();
238      }
239    }
240
241    public virtual void AddChildHiveTask(HiveTask hiveTask) {
242      childHiveTasksLock.EnterWriteLock();
243      try {
244        this.childHiveTasks.Add(hiveTask);
245      } finally { childHiveTasksLock.ExitWriteLock(); }
246    }
247
248    public override string ToString() {
249      if (itemTask != null && itemTask.Item != null) {
250        return itemTask.ToString();
251      } else {
252        return Task.Id.ToString();
253      }
254    }
255
256    public virtual void UpdateFromLightweightJob(LightweightTask lightweightJob) {
257      if (lightweightJob != null) {
258        task.Id = lightweightJob.Id;
259        task.ParentTaskId = lightweightJob.ParentTaskId;
260        task.ExecutionTime = lightweightJob.ExecutionTime;
261        task.State = lightweightJob.State;
262        task.StateLog = new List<StateLog>(lightweightJob.StateLog);
263        task.Command = lightweightJob.Command;
264
265        OnTaskStateChanged();
266        OnToStringChanged();
267        OnItemImageChanged();
268        OnStateLogChanged();
269      }
270    }
271
272    /// <summary>
273    /// Creates a TaskData object containing the Task and the IJob-Object as byte[]
274    /// </summary>
275    /// <param name="withoutChildOptimizers">
276    ///   if true the Child-Optimizers will not be serialized (if the task contains an Experiment)
277    /// </param>
278    public virtual TaskData GetAsTaskData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
279      plugins = new List<IPluginDescription>();
280      if (this.itemTask == null)
281        return null;
282
283      IEnumerable<Type> usedTypes;
284      byte[] taskByteArray = PersistenceUtil.Serialize(this.ItemTask, out usedTypes);
285      TaskData taskData = new TaskData() { TaskId = task.Id, Data = taskByteArray };
286      PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
287      return taskData;
288    }
289
290    #region Event Handler
291    public event EventHandler TaskChanged;
292    private void OnTaskChanged() {
293      EventHandler handler = TaskChanged;
294      if (handler != null) handler(this, EventArgs.Empty);
295    }
296
297    public event EventHandler TaskStateChanged;
298    private void OnTaskStateChanged() {
299      EventHandler handler = TaskStateChanged;
300      if (handler != null) handler(this, EventArgs.Empty);
301    }
302
303    public event EventHandler ItemTaskChanged;
304    private void OnItemTaskChanged() {
305      ItemJob_ComputeInParallelChanged(this, EventArgs.Empty);
306      var handler = ItemTaskChanged;
307      if (handler != null) handler(this, EventArgs.Empty);
308    }
309
310    public event EventHandler IsFinishedJobDownloadedChanged;
311    private void OnIsFinishedJobDownloadedChanged() {
312      var handler = IsFinishedJobDownloadedChanged;
313      if (handler != null) handler(this, EventArgs.Empty);
314    }
315
316    public event EventHandler StateLogChanged;
317    private void OnStateLogChanged() {
318      var handler = StateLogChanged;
319      if (handler != null) handler(this, EventArgs.Empty);
320    }
321
322    public event EventHandler IsControllableChanged;
323    private void OnIsControllableChanged() {
324      var handler = IsControllableChanged;
325      if (handler != null) handler(this, EventArgs.Empty);
326    }
327
328    private void RegisterJobEvents() {
329      if (task != null)
330        task.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
331    }
332
333    private void DeregisterJobEvents() {
334      if (task != null)
335        task.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
336    }
337
338    private void job_PropertyChanged(object sender, PropertyChangedEventArgs e) {
339      if (e.PropertyName == "State") {
340        IsFinishedTaskDownloaded = false;
341      }
342      if (e.PropertyName == "Priority" && Task != null) {
343        foreach (var task in childHiveTasks) {
344          task.Task.Priority = Task.Priority;
345        }
346      }
347    }
348    #endregion
349
350    /// <summary>
351    /// Returns a list of HiveTasks including this and all its child-jobs recursively
352    /// </summary>
353    public IEnumerable<HiveTask> GetAllHiveTasks() {
354      childHiveTasksLock.EnterReadLock();
355      try {
356        var jobs = new List<HiveTask>();
357        jobs.Add(this);
358        foreach (HiveTask child in this.childHiveTasks) {
359          jobs.AddRange(child.GetAllHiveTasks());
360        }
361        return jobs;
362      } finally { childHiveTasksLock.ExitReadLock(); }
363    }
364
365    public HiveTask GetParentByJobId(Guid taskId) {
366      childHiveTasksLock.EnterReadLock();
367      try {
368        if (this.ChildHiveTasks.SingleOrDefault(j => j.task.Id == taskId) != null)
369          return this;
370        foreach (HiveTask child in this.childHiveTasks) {
371          HiveTask result = child.GetParentByJobId(taskId);
372          if (result != null)
373            return result;
374        }
375        return null;
376      } finally { childHiveTasksLock.ExitWriteLock(); }
377    }
378
379    /// <summary>
380    /// Searches for an HiveTask object with the correct taskId recursively
381    /// </summary>
382    public HiveTask GetHiveTaskByTaskId(Guid jobId) {
383      if (this.Task.Id == jobId) {
384        return this;
385      } else {
386        childHiveTasksLock.EnterReadLock();
387        try {
388          foreach (HiveTask child in this.childHiveTasks) {
389            HiveTask result = child.GetHiveTaskByTaskId(jobId);
390            if (result != null)
391              return result;
392          }
393        } finally { childHiveTasksLock.ExitReadLock(); }
394      }
395      return null;
396    }
397
398    public void RemoveByTaskId(Guid jobId) {
399      childHiveTasksLock.EnterWriteLock();
400      try {
401        IEnumerable<HiveTask> jobs = childHiveTasks.Where(j => j.Task.Id == jobId).ToList();
402        foreach (HiveTask j in jobs) {
403          this.childHiveTasks.Remove(j);
404        }
405        foreach (HiveTask child in childHiveTasks) {
406          child.RemoveByTaskId(jobId);
407        }
408      } finally { childHiveTasksLock.ExitWriteLock(); }
409    }
410
411    public IEnumerable<IItemTree<HiveTask>> GetChildItems() {
412      return this.ChildHiveTasks;
413    }
414
415    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
416
417    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> CollectionReset;
418    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
419      foreach (var item in e.Items) {
420        item.Value.StateLogChanged -= new EventHandler(ChildHiveJob_StateLogChanged);
421      }
422      var handler = CollectionReset;
423      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
424    }
425
426    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> ItemsAdded;
427    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
428      foreach (var item in e.Items) {
429        item.Value.StateLogChanged += new EventHandler(ChildHiveJob_StateLogChanged);
430        item.Value.IsControllable = this.IsControllable;
431      }
432      var handler = ItemsAdded;
433      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
434    }
435
436    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> ItemsRemoved;
437    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
438      foreach (var item in e.Items) {
439        item.Value.StateLogChanged -= new EventHandler(ChildHiveJob_StateLogChanged);
440      }
441      var handler = ItemsRemoved;
442      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
443    }
444
445    private static CollectionItemsChangedEventArgs<IItemTree<HiveTask>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
446      return new CollectionItemsChangedEventArgs<IItemTree<HiveTask>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
447    }
448
449    private void ChildHiveJob_StateLogChanged(object sender, EventArgs e) {
450      OnStateLogChanged();
451    }
452    #endregion
453
454    public void Pause() {
455      if (this.Task.IsParentTask) {
456        childHiveTasksLock.EnterReadLock();
457        try {
458          foreach (var child in childHiveTasks) {
459            HiveServiceLocator.Instance.CallHiveService(s => s.PauseTask(child.task.Id));
460          }
461        } finally { childHiveTasksLock.ExitReadLock(); }
462      } else {
463        HiveServiceLocator.Instance.CallHiveService(s => s.PauseTask(this.task.Id));
464      }
465    }
466
467    public void Stop() {
468      if (this.Task.IsParentTask) {
469        childHiveTasksLock.EnterReadLock();
470        try {
471          foreach (var child in childHiveTasks) {
472            HiveServiceLocator.Instance.CallHiveService(s => s.StopTask(child.task.Id));
473          }
474        } finally { childHiveTasksLock.ExitReadLock(); }
475      } else {
476        HiveServiceLocator.Instance.CallHiveService(s => s.StopTask(this.task.Id));
477      }
478    }
479
480    public void Restart() {
481      HiveServiceLocator.Instance.CallHiveService(service => {
482        TaskData taskData = new TaskData();
483        taskData.TaskId = this.task.Id;
484        taskData.Data = PersistenceUtil.Serialize(this.itemTask);
485        service.UpdateTaskData(this.Task, taskData);
486        service.RestartTask(this.task.Id);
487        Task task = service.GetTask(this.task.Id);
488        this.task.LastTaskDataUpdate = task.LastTaskDataUpdate;
489      });
490    }
491
492    public ICollection<IItemTreeNodeAction<HiveTask>> Actions {
493      get {
494        return new List<IItemTreeNodeAction<HiveTask>>();
495      }
496    }
497
498    public virtual void IntegrateChild(ItemTask task, Guid childTaskId) { }
499
500    /// <summary>
501    /// Delete ItemTask
502    /// </summary>
503    public virtual void ClearData() {
504      this.ItemTask.Item = null;
505    }
506  }
507
508  [Item("Hive Task", "Represents a hive task.")]
509  [StorableClass]
510  public class HiveTask<T> : HiveTask where T : ItemTask {
511
512    public new T ItemTask {
513      get { return (T)base.ItemTask; }
514      internal set { base.ItemTask = value; }
515    }
516
517    #region Constructors and Cloning
518    public HiveTask() : base() { }
519    [StorableConstructor]
520    protected HiveTask(bool deserializing) { }
521    public HiveTask(T itemJob) : base(itemJob, true) { }
522    protected HiveTask(HiveTask<T> original, Cloner cloner)
523      : base(original, cloner) {
524    }
525    public override IDeepCloneable Clone(Cloner cloner) {
526      return new HiveTask<T>(this, cloner);
527    }
528    #endregion
529  }
530}
Note: See TracBrowser for help on using the repository browser.