Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1672

  • removed magic numbers for upload retries
  • speed up job downloading by placing deserializing/downloading semaphores correctly
  • increased max. number of parallel downloads/deserializations
  • added more status messages when downloading to make it more clear what's actually happening
  • renamed some variables
File size: 18.8 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          }
124          finally {
125            childHiveTasksLock.ExitReadLock();
126          }
127        }
128      }
129    }
130
131    [Storable]
132    protected ItemList<HiveTask> childHiveTasks;
133    public virtual ReadOnlyItemList<HiveTask> ChildHiveTasks {
134      get {
135        childHiveTasksLock.EnterReadLock();
136        try {
137          return childHiveTasks.AsReadOnly();
138        }
139        finally { childHiveTasksLock.ExitReadLock(); }
140      }
141    }
142
143    [Storable]
144    protected bool syncTasksWithOptimizers = true;
145
146    public StateLogList StateLog {
147      get { return new StateLogList(this.task.StateLog); }
148    }
149
150    public StateLogListList ChildStateLogList {
151      get { return new StateLogListList(this.childHiveTasks.Select(x => x.StateLog)); }
152    }
153
154    #region Constructors and Cloning
155    [StorableConstructor]
156    protected HiveTask(bool deserializing) { }
157
158    public HiveTask() {
159      this.Task = new Task() { CoresNeeded = 1, MemoryNeeded = 0 };
160      task.State = TaskState.Offline;
161      this.childHiveTasks = new ItemList<HiveTask>();
162      syncTasksWithOptimizers = true;
163      RegisterChildHiveJobEvents();
164    }
165
166    public HiveTask(ItemTask itemJob, bool autoCreateChildHiveJobs)
167      : this() {
168      this.syncTasksWithOptimizers = autoCreateChildHiveJobs;
169      this.ItemTask = itemJob;
170      this.syncTasksWithOptimizers = true;
171    }
172
173    public HiveTask(Task job, TaskData taskData, bool autoCreateChildHiveTasks) {
174      this.syncTasksWithOptimizers = autoCreateChildHiveTasks;
175      this.Task = job;
176      try {
177        this.ItemTask = PersistenceUtil.Deserialize<ItemTask>(taskData.Data);
178      }
179      catch {
180        this.ItemTask = null;
181      }
182      this.childHiveTasks = new ItemList<HiveTask>();
183      this.syncTasksWithOptimizers = true;
184      RegisterChildHiveJobEvents();
185    }
186
187    protected HiveTask(HiveTask original, Cloner cloner)
188      : base(original, cloner) {
189      this.Task = cloner.Clone(original.task);
190      this.ItemTask = cloner.Clone(original.ItemTask);
191      original.childHiveTasksLock.EnterReadLock();
192      try {
193        this.childHiveTasks = cloner.Clone(original.childHiveTasks);
194      }
195      finally { original.childHiveTasksLock.ExitReadLock(); }
196      this.syncTasksWithOptimizers = original.syncTasksWithOptimizers;
197      this.isFinishedTaskDownloaded = original.isFinishedTaskDownloaded;
198    }
199    public override IDeepCloneable Clone(Cloner cloner) {
200      return new HiveTask(this, cloner);
201    }
202    #endregion
203
204    protected virtual void UpdateChildHiveTasks() { }
205
206    protected virtual void RegisterItemTaskEvents() {
207      if (ItemTask != null) {
208        ItemTask.ComputeInParallelChanged += new EventHandler(ItemJob_ComputeInParallelChanged);
209        ItemTask.ToStringChanged += new EventHandler(ItemJob_ToStringChanged);
210      }
211    }
212    protected virtual void DergisterItemTaskEvents() {
213      if (ItemTask != null) {
214        ItemTask.ComputeInParallelChanged -= new EventHandler(ItemJob_ComputeInParallelChanged);
215        ItemTask.ToStringChanged -= new EventHandler(ItemJob_ToStringChanged);
216      }
217    }
218
219    protected virtual void RegisterChildHiveJobEvents() {
220      this.childHiveTasks.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsAdded);
221      this.childHiveTasks.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsRemoved);
222      this.childHiveTasks.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnCollectionReset);
223    }
224    protected virtual void DeregisterChildHiveJobEvents() {
225      this.childHiveTasks.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsAdded);
226      this.childHiveTasks.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnItemsRemoved);
227      this.childHiveTasks.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveTask>>(OnCollectionReset);
228    }
229
230    protected virtual void ItemJob_ToStringChanged(object sender, EventArgs e) {
231      this.OnToStringChanged();
232    }
233
234    protected virtual void ItemJob_ComputeInParallelChanged(object sender, EventArgs e) {
235      if (ItemTask != null && syncTasksWithOptimizers) {
236        this.UpdateChildHiveTasks();
237      }
238    }
239
240    public virtual void AddChildHiveTask(HiveTask hiveTask) {
241      childHiveTasksLock.EnterWriteLock();
242      try {
243        this.childHiveTasks.Add(hiveTask);
244      }
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    }
343    #endregion
344
345    /// <summary>
346    /// Returns a list of HiveTasks including this and all its child-jobs recursively
347    /// </summary>
348    public IEnumerable<HiveTask> GetAllHiveTasks() {
349      childHiveTasksLock.EnterReadLock();
350      try {
351        var jobs = new List<HiveTask>();
352        jobs.Add(this);
353        foreach (HiveTask child in this.childHiveTasks) {
354          jobs.AddRange(child.GetAllHiveTasks());
355        }
356        return jobs;
357      }
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      }
373      finally { childHiveTasksLock.ExitWriteLock(); }
374    }
375
376    /// <summary>
377    /// Searches for an HiveTask object with the correct taskId recursively
378    /// </summary>
379    public HiveTask GetHiveTaskByTaskId(Guid jobId) {
380      if (this.Task.Id == jobId) {
381        return this;
382      } else {
383        childHiveTasksLock.EnterReadLock();
384        try {
385          foreach (HiveTask child in this.childHiveTasks) {
386            HiveTask result = child.GetHiveTaskByTaskId(jobId);
387            if (result != null)
388              return result;
389          }
390        }
391        finally { childHiveTasksLock.ExitReadLock(); }
392      }
393      return null;
394    }
395
396    public void RemoveByTaskId(Guid jobId) {
397      childHiveTasksLock.EnterWriteLock();
398      try {
399        IEnumerable<HiveTask> jobs = childHiveTasks.Where(j => j.Task.Id == jobId).ToList();
400        foreach (HiveTask j in jobs) {
401          this.childHiveTasks.Remove(j);
402        }
403        foreach (HiveTask child in childHiveTasks) {
404          child.RemoveByTaskId(jobId);
405        }
406      }
407      finally { childHiveTasksLock.ExitWriteLock(); }
408    }
409
410    public IEnumerable<IItemTree<HiveTask>> GetChildItems() {
411      return this.ChildHiveTasks;
412    }
413
414    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
415
416    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> CollectionReset;
417    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
418      foreach (var item in e.Items) {
419        item.Value.StateLogChanged -= new EventHandler(ChildHiveJob_StateLogChanged);
420      }
421      var handler = CollectionReset;
422      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
423    }
424
425    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> ItemsAdded;
426    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
427      foreach (var item in e.Items) {
428        item.Value.StateLogChanged += new EventHandler(ChildHiveJob_StateLogChanged);
429        item.Value.IsControllable = this.IsControllable;
430      }
431      var handler = ItemsAdded;
432      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
433    }
434
435    public event CollectionItemsChangedEventHandler<IItemTree<HiveTask>> ItemsRemoved;
436    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
437      foreach (var item in e.Items) {
438        item.Value.StateLogChanged -= new EventHandler(ChildHiveJob_StateLogChanged);
439      }
440      var handler = ItemsRemoved;
441      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
442    }
443
444    private static CollectionItemsChangedEventArgs<IItemTree<HiveTask>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveTask>> e) {
445      return new CollectionItemsChangedEventArgs<IItemTree<HiveTask>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
446    }
447
448    private void ChildHiveJob_StateLogChanged(object sender, EventArgs e) {
449      OnStateLogChanged();
450    }
451    #endregion
452
453    public void Pause() {
454      if (this.Task.IsParentTask) {
455        childHiveTasksLock.EnterReadLock();
456        try {
457          foreach (var child in childHiveTasks) {
458            ServiceLocator.Instance.CallHiveService(s => s.PauseTask(child.task.Id));
459          }
460        }
461        finally { childHiveTasksLock.ExitReadLock(); }
462      } else {
463        ServiceLocator.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            ServiceLocator.Instance.CallHiveService(s => s.StopTask(child.task.Id));
473          }
474        }
475        finally { childHiveTasksLock.ExitReadLock(); }
476      } else {
477        ServiceLocator.Instance.CallHiveService(s => s.StopTask(this.task.Id));
478      }
479    }
480
481    public void Restart() {
482      ServiceLocator.Instance.CallHiveService(service => {
483        TaskData taskData = new TaskData();
484        taskData.TaskId = this.task.Id;
485        taskData.Data = PersistenceUtil.Serialize(this.itemTask);
486        service.UpdateTaskData(this.Task, taskData);
487        service.RestartTask(this.task.Id);
488        Task task = service.GetTask(this.task.Id);
489        this.task.LastTaskDataUpdate = task.LastTaskDataUpdate;
490      });
491    }
492
493    public ICollection<IItemTreeNodeAction<HiveTask>> Actions {
494      get {
495        return new List<IItemTreeNodeAction<HiveTask>>();
496      }
497    }
498
499    public virtual void IntegrateChild(ItemTask task, Guid childTaskId) { }
500
501    /// <summary>
502    /// Delete ItemTask
503    /// </summary>
504    public virtual void ClearData() {
505      this.ItemTask.Item = null;
506    }
507  }
508
509  [Item("Hive Task", "Represents a hive task.")]
510  [StorableClass]
511  public class HiveTask<T> : HiveTask where T : ItemTask {
512
513    public new T ItemTask {
514      get { return (T)base.ItemTask; }
515      internal set { base.ItemTask = value; }
516    }
517
518    #region Constructors and Cloning
519    public HiveTask() : base() { }
520    [StorableConstructor]
521    protected HiveTask(bool deserializing) { }
522    public HiveTask(T itemJob) : base(itemJob, true) { }
523    protected HiveTask(HiveTask<T> original, Cloner cloner)
524      : base(original, cloner) {
525    }
526    public override IDeepCloneable Clone(Cloner cloner) {
527      return new HiveTask<T>(this, cloner);
528    }
529    #endregion
530  }
531}
Note: See TracBrowser for help on using the repository browser.