source: stable/HeuristicLab.Clients.Hive/3.3/HiveTasks/HiveTask.cs @ 11083

Last change on this file since 11083 was 11083, checked in by ascheibe, 5 years ago

#2117 merged r10130, r10150, r10154, r10170, r11079 into stable

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