Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Clients.Hive/3.3/HiveTasks/HiveTask.cs @ 16003

Last change on this file since 16003 was 13656, checked in by ascheibe, 9 years ago

#2582 created branch for Hive Web Job Manager

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