Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PersistenceReintegration/HeuristicLab.Clients.Hive/3.3/HiveTasks/HiveTask.cs @ 14927

Last change on this file since 14927 was 14927, checked in by gkronber, 7 years ago

#2520: changed all usages of StorableClass to use StorableType with an auto-generated GUID (did not add StorableType to other type definitions yet)

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