Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1672 fixed setting of priorities in the Job Manager

File size: 18.9 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 { return new StateLogList(this.task.StateLog); }
146    }
147
148    public StateLogListList ChildStateLogList {
149      get { return new StateLogListList(this.childHiveTasks.Select(x => x.StateLog)); }
150    }
151
152    #region Constructors and Cloning
153    [StorableConstructor]
154    protected HiveTask(bool deserializing) { }
155
156    public HiveTask() {
157      this.Task = new Task() { CoresNeeded = 1, MemoryNeeded = 0 };
158      task.State = TaskState.Offline;
159      this.childHiveTasks = new ItemList<HiveTask>();
160      syncTasksWithOptimizers = true;
161      RegisterChildHiveJobEvents();
162    }
163
164    public HiveTask(ItemTask itemJob, bool autoCreateChildHiveJobs)
165      : this() {
166      this.syncTasksWithOptimizers = autoCreateChildHiveJobs;
167      this.ItemTask = itemJob;
168      this.syncTasksWithOptimizers = true;
169    }
170
171    public HiveTask(Task job, TaskData taskData, bool autoCreateChildHiveTasks) {
172      this.syncTasksWithOptimizers = autoCreateChildHiveTasks;
173      this.Task = job;
174      try {
175        this.ItemTask = PersistenceUtil.Deserialize<ItemTask>(taskData.Data);
176      }
177      catch {
178        this.ItemTask = null;
179      }
180      this.childHiveTasks = new ItemList<HiveTask>();
181      this.syncTasksWithOptimizers = true;
182      RegisterChildHiveJobEvents();
183    }
184
185    protected HiveTask(HiveTask original, Cloner cloner)
186      : base(original, cloner) {
187      this.Task = cloner.Clone(original.task);
188      this.ItemTask = cloner.Clone(original.ItemTask);
189      original.childHiveTasksLock.EnterReadLock();
190      try {
191        this.childHiveTasks = cloner.Clone(original.childHiveTasks);
192      } finally { original.childHiveTasksLock.ExitReadLock(); }
193      this.syncTasksWithOptimizers = original.syncTasksWithOptimizers;
194      this.isFinishedTaskDownloaded = original.isFinishedTaskDownloaded;
195    }
196    public override IDeepCloneable Clone(Cloner cloner) {
197      return new HiveTask(this, cloner);
198    }
199    #endregion
200
201    protected virtual void UpdateChildHiveTasks() { }
202
203    protected virtual void RegisterItemTaskEvents() {
204      if (ItemTask != null) {
205        ItemTask.ComputeInParallelChanged += new EventHandler(ItemJob_ComputeInParallelChanged);
206        ItemTask.ToStringChanged += new EventHandler(ItemJob_ToStringChanged);
207      }
208    }
209    protected virtual void DergisterItemTaskEvents() {
210      if (ItemTask != null) {
211        ItemTask.ComputeInParallelChanged -= new EventHandler(ItemJob_ComputeInParallelChanged);
212        ItemTask.ToStringChanged -= new EventHandler(ItemJob_ToStringChanged);
213      }
214    }
215
216    protected virtual void RegisterChildHiveJobEvents() {
217      this.childHiveTasks.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsAdded);
218      this.childHiveTasks.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsRemoved);
219      this.childHiveTasks.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnCollectionReset);
220    }
221    protected virtual void DeregisterChildHiveJobEvents() {
222      this.childHiveTasks.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsAdded);
223      this.childHiveTasks.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsRemoved);
224      this.childHiveTasks.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnCollectionReset);
225    }
226
227    protected virtual void ItemJob_ToStringChanged(object sender, EventArgs e) {
228      this.OnToStringChanged();
229    }
230
231    protected virtual void ItemJob_ComputeInParallelChanged(object sender, EventArgs e) {
232      if (ItemTask != null && syncTasksWithOptimizers) {
233        this.UpdateChildHiveTasks();
234      }
235    }
236
237    public virtual void AddChildHiveTask(HiveTask hiveTask) {
238      childHiveTasksLock.EnterWriteLock();
239      try {
240        this.childHiveTasks.Add(hiveTask);
241      } finally { childHiveTasksLock.ExitWriteLock(); }
242    }
243
244    public override string ToString() {
245      if (itemTask != null && itemTask.Item != null) {
246        return itemTask.ToString();
247      } else {
248        return Task.Id.ToString();
249      }
250    }
251
252    public virtual void UpdateFromLightweightJob(LightweightTask lightweightJob) {
253      if (lightweightJob != null) {
254        task.Id = lightweightJob.Id;
255        task.ParentTaskId = lightweightJob.ParentTaskId;
256        task.ExecutionTime = lightweightJob.ExecutionTime;
257        task.State = lightweightJob.State;
258        task.StateLog = new List<StateLog>(lightweightJob.StateLog);
259        task.Command = lightweightJob.Command;
260
261        OnTaskStateChanged();
262        OnToStringChanged();
263        OnItemImageChanged();
264        OnStateLogChanged();
265      }
266    }
267
268    /// <summary>
269    /// Creates a TaskData object containing the Task and the IJob-Object as byte[]
270    /// </summary>
271    /// <param name="withoutChildOptimizers">
272    ///   if true the Child-Optimizers will not be serialized (if the task contains an Experiment)
273    /// </param>
274    public virtual TaskData GetAsTaskData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
275      plugins = new List<IPluginDescription>();
276      if (this.itemTask == null)
277        return null;
278
279      IEnumerable<Type> usedTypes;
280      byte[] taskByteArray = PersistenceUtil.Serialize(this.ItemTask, out usedTypes);
281      TaskData taskData = new TaskData() { TaskId = task.Id, Data = taskByteArray };
282      PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
283      return taskData;
284    }
285
286    #region Event Handler
287    public event EventHandler TaskChanged;
288    private void OnTaskChanged() {
289      EventHandler handler = TaskChanged;
290      if (handler != null) handler(this, EventArgs.Empty);
291    }
292
293    public event EventHandler TaskStateChanged;
294    private void OnTaskStateChanged() {
295      EventHandler handler = TaskStateChanged;
296      if (handler != null) handler(this, EventArgs.Empty);
297    }
298
299    public event EventHandler ItemTaskChanged;
300    private void OnItemTaskChanged() {
301      ItemJob_ComputeInParallelChanged(this, EventArgs.Empty);
302      var handler = ItemTaskChanged;
303      if (handler != null) handler(this, EventArgs.Empty);
304    }
305
306    public event EventHandler IsFinishedJobDownloadedChanged;
307    private void OnIsFinishedJobDownloadedChanged() {
308      var handler = IsFinishedJobDownloadedChanged;
309      if (handler != null) handler(this, EventArgs.Empty);
310    }
311
312    public event EventHandler StateLogChanged;
313    private void OnStateLogChanged() {
314      var handler = StateLogChanged;
315      if (handler != null) handler(this, EventArgs.Empty);
316    }
317
318    public event EventHandler IsControllableChanged;
319    private void OnIsControllableChanged() {
320      var handler = IsControllableChanged;
321      if (handler != null) handler(this, EventArgs.Empty);
322    }
323
324    private void RegisterJobEvents() {
325      if (task != null)
326        task.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
327    }
328
329    private void DeregisterJobEvents() {
330      if (task != null)
331        task.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
332    }
333
334    private void job_PropertyChanged(object sender, PropertyChangedEventArgs e) {
335      if (e.PropertyName == "State") {
336        IsFinishedTaskDownloaded = false;
337      }
338      if (e.PropertyName == "Priority" && Task != null) {
339        foreach (var task in childHiveTasks) {
340          task.Task.Priority = Task.Priority;
341        }
342      }
343    }
344    #endregion
345
346    /// <summary>
347    /// Returns a list of HiveTasks including this and all its child-jobs recursively
348    /// </summary>
349    public IEnumerable<HiveTask> GetAllHiveTasks() {
350      childHiveTasksLock.EnterReadLock();
351      try {
352        var jobs = new List<HiveTask>();
353        jobs.Add(this);
354        foreach (HiveTask child in this.childHiveTasks) {
355          jobs.AddRange(child.GetAllHiveTasks());
356        }
357        return jobs;
358      } finally { childHiveTasksLock.ExitReadLock(); }
359    }
360
361    public HiveTask GetParentByJobId(Guid taskId) {
362      childHiveTasksLock.EnterReadLock();
363      try {
364        if (this.ChildHiveTasks.SingleOrDefault(j => j.task.Id == taskId) != null)
365          return this;
366        foreach (HiveTask child in this.childHiveTasks) {
367          HiveTask result = child.GetParentByJobId(taskId);
368          if (result != null)
369            return result;
370        }
371        return null;
372      } finally { childHiveTasksLock.ExitWriteLock(); }
373    }
374
375    /// <summary>
376    /// Searches for an HiveTask object with the correct taskId recursively
377    /// </summary>
378    public HiveTask GetHiveTaskByTaskId(Guid jobId) {
379      if (this.Task.Id == jobId) {
380        return this;
381      } else {
382        childHiveTasksLock.EnterReadLock();
383        try {
384          foreach (HiveTask child in this.childHiveTasks) {
385            HiveTask result = child.GetHiveTaskByTaskId(jobId);
386            if (result != null)
387              return result;
388          }
389        } finally { childHiveTasksLock.ExitReadLock(); }
390      }
391      return null;
392    }
393
394    public void RemoveByTaskId(Guid jobId) {
395      childHiveTasksLock.EnterWriteLock();
396      try {
397        IEnumerable<HiveTask> jobs = childHiveTasks.Where(j => j.Task.Id == jobId).ToList();
398        foreach (HiveTask j in jobs) {
399          this.childHiveTasks.Remove(j);
400        }
401        foreach (HiveTask child in childHiveTasks) {
402          child.RemoveByTaskId(jobId);
403        }
404      } finally { childHiveTasksLock.ExitWriteLock(); }
405    }
406
407    public IEnumerable<IItemTree<HiveTask>> GetChildItems() {
408      return this.ChildHiveTasks;
409    }
410
411    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
412
413    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> CollectionReset;
414    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
415      foreach (var item in e.Items) {
416        item.Value.StateLogChanged -= new EventHandler(ChildHiveJob_StateLogChanged);
417      }
418      var handler = CollectionReset;
419      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
420    }
421
422    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> ItemsAdded;
423    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
424      foreach (var item in e.Items) {
425        item.Value.StateLogChanged += new EventHandler(ChildHiveJob_StateLogChanged);
426        item.Value.IsControllable = this.IsControllable;
427      }
428      var handler = ItemsAdded;
429      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
430    }
431
432    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> ItemsRemoved;
433    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
434      foreach (var item in e.Items) {
435        item.Value.StateLogChanged -= new EventHandler(ChildHiveJob_StateLogChanged);
436      }
437      var handler = ItemsRemoved;
438      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
439    }
440
441    private static CollectionItemsChangedEventArgs<IItemTree<HiveTask>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
442      return new CollectionItemsChangedEventArgs<IItemTree<HiveTask>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
443    }
444
445    private void ChildHiveJob_StateLogChanged(object sender, EventArgs e) {
446      OnStateLogChanged();
447    }
448    #endregion
449
450    public void Pause() {
451      if (this.Task.IsParentTask) {
452        childHiveTasksLock.EnterReadLock();
453        try {
454          foreach (var child in childHiveTasks) {
455            HiveServiceLocator.Instance.CallHiveService(s => s.PauseTask(child.task.Id));
456          }
457        } finally { childHiveTasksLock.ExitReadLock(); }
458      } else {
459        HiveServiceLocator.Instance.CallHiveService(s => s.PauseTask(this.task.Id));
460      }
461    }
462
463    public void Stop() {
464      if (this.Task.IsParentTask) {
465        childHiveTasksLock.EnterReadLock();
466        try {
467          foreach (var child in childHiveTasks) {
468            HiveServiceLocator.Instance.CallHiveService(s => s.StopTask(child.task.Id));
469          }
470        } finally { childHiveTasksLock.ExitReadLock(); }
471      } else {
472        HiveServiceLocator.Instance.CallHiveService(s => s.StopTask(this.task.Id));
473      }
474    }
475
476    public void Restart() {
477      HiveServiceLocator.Instance.CallHiveService(service => {
478        TaskData taskData = new TaskData();
479        taskData.TaskId = this.task.Id;
480        taskData.Data = PersistenceUtil.Serialize(this.itemTask);
481        service.UpdateTaskData(this.Task, taskData);
482        service.RestartTask(this.task.Id);
483        Task task = service.GetTask(this.task.Id);
484        this.task.LastTaskDataUpdate = task.LastTaskDataUpdate;
485      });
486    }
487
488    public ICollection<IItemTreeNodeAction<HiveTask>> Actions {
489      get {
490        return new List<IItemTreeNodeAction<HiveTask>>();
491      }
492    }
493
494    public virtual void IntegrateChild(ItemTask task, Guid childTaskId) { }
495
496    /// <summary>
497    /// Delete ItemTask
498    /// </summary>
499    public virtual void ClearData() {
500      this.ItemTask.Item = null;
501    }
502  }
503
504  [Item("Hive Task", "Represents a hive task.")]
505  [StorableClass]
506  public class HiveTask<T> : HiveTask where T : ItemTask {
507
508    public new T ItemTask {
509      get { return (T)base.ItemTask; }
510      internal set { base.ItemTask = value; }
511    }
512
513    #region Constructors and Cloning
514    public HiveTask() : base() { }
515    [StorableConstructor]
516    protected HiveTask(bool deserializing) { }
517    public HiveTask(T itemJob) : base(itemJob, true) { }
518    protected HiveTask(HiveTask<T> original, Cloner cloner)
519      : base(original, cloner) {
520    }
521    public override IDeepCloneable Clone(Cloner cloner) {
522      return new HiveTask<T>(this, cloner);
523    }
524    #endregion
525  }
526}
Note: See TracBrowser for help on using the repository browser.