Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs @ 6200

Last change on this file since 6200 was 6200, checked in by cneumuel, 13 years ago

#1233

  • stability improvements for HiveEngine
File size: 15.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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 HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Hive;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Clients.Hive {
35
36  [Item("Hive Job", "Represents a hive job.")]
37  [StorableClass]
38  public class HiveJob : NamedItem, IItemTree<HiveJob> {
39    protected static object locker = new object();
40
41    public override Image ItemImage {
42      get {
43        if (job.Id == Guid.Empty) { // not yet uploaded
44          return HeuristicLab.Common.Resources.VSImageLibrary.Event;
45        } else {
46          if (job.State == JobState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
47          else if (job.State == JobState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
48          else if (job.State == JobState.Transferring) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
49          else if (job.State == JobState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
50          else if (job.State == JobState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
51          else if (job.State == JobState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
52          else if (job.State == JobState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
53          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
54        }
55      }
56    }
57
58    [Storable]
59    protected Job job;
60    public Job Job {
61      get { return job; }
62      set {
63        if (job != value) {
64          DeregisterJobEvents();
65          job = value;
66          RegisterJobEvents();
67          IsFinishedJobDownloaded = false;
68          OnJobChanged();
69          OnToStringChanged();
70          OnItemImageChanged();
71        }
72       
73      }
74    }
75
76    [Storable]
77    protected ItemJob itemJob;
78    public ItemJob ItemJob {
79      get { return itemJob; }
80      internal set {
81        if (itemJob != null && syncJobsWithOptimizers) {
82          this.childHiveJobs.Clear();
83        }
84        if (itemJob != value) {
85          DergisterItemJobEvents();
86          itemJob = value;
87          RegisterItemJobEvents();
88          OnItemJobChanged();
89          IsFinishedJobDownloaded = true;
90        }
91      }
92    }
93
94    // job downloaded since last status change
95    [Storable]
96    private bool isFinishedJobDownloaded = false;
97    public bool IsFinishedJobDownloaded {
98      get { return isFinishedJobDownloaded; }
99      set {
100        if (value != isFinishedJobDownloaded) {
101          this.isFinishedJobDownloaded = value;
102          OnIsFinishedJobDownloadedChanged();
103        }
104      }
105    }
106
107    public bool IsDownloading { get; set; }
108
109    [Storable]
110    protected ItemList<HiveJob> childHiveJobs;
111    public virtual ReadOnlyItemList<HiveJob> ChildHiveJobs {
112      get { return childHiveJobs.AsReadOnly(); }
113    }
114
115    [Storable]
116    protected bool syncJobsWithOptimizers = true;
117
118    #region Constructors and Cloning
119    public HiveJob() {
120      this.Job = new Job() {
121        CoresNeeded = 1,
122        MemoryNeeded = 0
123      };
124      job.State = JobState.Offline;
125      this.childHiveJobs = new ItemList<HiveJob>();
126      syncJobsWithOptimizers = true;
127      RegisterChildHiveJobEvents();
128    }
129
130    public HiveJob(ItemJob itemJob, bool autoCreateChildHiveJobs)
131      : this() {
132      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
133      this.ItemJob = itemJob;
134      this.syncJobsWithOptimizers = true;
135    }
136
137    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs) {
138      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
139      this.Job = job;
140      try {
141        this.ItemJob = PersistenceUtil.Deserialize<ItemJob>(jobData.Data);
142      }
143      catch {
144        this.ItemJob = null;
145      }
146      this.childHiveJobs = new ItemList<HiveJob>();
147      this.syncJobsWithOptimizers = true;
148      RegisterChildHiveJobEvents();
149    }
150
151    protected HiveJob(HiveJob original, Cloner cloner)
152      : base(original, cloner) {
153      this.Job = cloner.Clone(original.job);
154      this.ItemJob = cloner.Clone(original.ItemJob);
155      this.childHiveJobs = cloner.Clone(original.childHiveJobs);
156      this.syncJobsWithOptimizers = original.syncJobsWithOptimizers;
157      this.isFinishedJobDownloaded = original.isFinishedJobDownloaded;
158    }
159    public override IDeepCloneable Clone(Cloner cloner) {
160      return new HiveJob(this, cloner);
161    }
162    #endregion
163
164    protected virtual void UpdateChildHiveJobs() { }
165
166    protected virtual void RegisterItemJobEvents() {
167      if (ItemJob != null) {
168        ItemJob.ComputeInParallelChanged += new EventHandler(ItemJob_ComputeInParallelChanged);
169        ItemJob.ToStringChanged += new EventHandler(ItemJob_ToStringChanged);
170      }
171    }
172    protected virtual void DergisterItemJobEvents() {
173      if (ItemJob != null) {
174        ItemJob.ComputeInParallelChanged -= new EventHandler(ItemJob_ComputeInParallelChanged);
175        ItemJob.ToStringChanged -= new EventHandler(ItemJob_ToStringChanged);
176      }
177    }
178
179    protected virtual void RegisterChildHiveJobEvents() {
180      this.childHiveJobs.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
181      this.childHiveJobs.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
182      this.childHiveJobs.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
183    }
184    protected virtual void DeregisterChildHiveJobEvents() {
185      this.childHiveJobs.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
186      this.childHiveJobs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
187      this.childHiveJobs.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
188    }
189
190    protected virtual void ItemJob_ToStringChanged(object sender, EventArgs e) {
191      this.OnToStringChanged();
192    }
193
194    protected virtual void ItemJob_ComputeInParallelChanged(object sender, EventArgs e) {
195      if (ItemJob != null && syncJobsWithOptimizers) {
196        this.UpdateChildHiveJobs();
197      }
198    }
199
200    public virtual void AddChildHiveJob(HiveJob hiveJob) {
201      this.childHiveJobs.Add(hiveJob);
202    }
203
204    public override string ToString() {
205      if (itemJob != null && itemJob.Item != null) {
206        return itemJob.ToString();
207      } else {
208        return Job.Id.ToString();
209      }
210    }
211
212    public virtual void UpdateFromLightweightJob(LightweightJob lightweightJob) {
213      if (lightweightJob != null) {
214        job.Id = lightweightJob.Id;
215        job.ParentJobId = lightweightJob.ParentJobId;
216        job.ExecutionTime = lightweightJob.ExecutionTime;
217        job.State = lightweightJob.State;
218        job.StateLog = new List<StateLog>(lightweightJob.StateLog);
219        job.Command = lightweightJob.Command;
220
221        OnJobStateChanged();
222        OnToStringChanged();
223        OnItemImageChanged();
224      }
225    }
226
227    /// <summary>
228    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
229    /// </summary>
230    /// <param name="withoutChildOptimizers">
231    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
232    /// </param>
233    public virtual JobData GetAsJobData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
234      plugins = new List<IPluginDescription>();
235      if (this.itemJob == null)
236        return null;
237
238      IEnumerable<Type> usedTypes;
239      byte[] jobByteArray = PersistenceUtil.Serialize(this.ItemJob, out usedTypes);
240
241      JobData jobData = new JobData() {
242        JobId = job.Id,
243        Data = jobByteArray
244      };
245
246      PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
247
248      return jobData;
249    }
250
251    #region Events
252    public event EventHandler JobChanged;
253    private void OnJobChanged() {
254      EventHandler handler = JobChanged;
255      if (handler != null) handler(this, EventArgs.Empty);
256    }
257
258    public event EventHandler JobStateChanged;
259    private void OnJobStateChanged() {
260      EventHandler handler = JobStateChanged;
261      if (handler != null) handler(this, EventArgs.Empty);
262    }
263
264    public event EventHandler ItemJobChanged;
265    private void OnItemJobChanged() {
266      ItemJob_ComputeInParallelChanged(this, EventArgs.Empty);
267      var handler = ItemJobChanged;
268      if (handler != null) handler(this, EventArgs.Empty);
269    }
270
271    public event EventHandler IsFinishedJobDownloadedChanged;
272    private void OnIsFinishedJobDownloadedChanged() {
273      var handler = IsFinishedJobDownloadedChanged;
274      if (handler != null) handler(this, EventArgs.Empty);
275    }
276
277    private void RegisterJobEvents() {
278      if (job != null)
279        job.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
280    }
281
282    private void DeregisterJobEvents() {
283      if (job != null)
284        job.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(job_PropertyChanged);
285    }
286
287    private void job_PropertyChanged(object sender, PropertyChangedEventArgs e) {
288      if (e.PropertyName == "State") {
289        IsFinishedJobDownloaded = false;
290      }
291    }
292    #endregion
293
294    /// <summary>
295    /// Returns a list of HiveJobs including this and all its child-jobs recursively
296    /// </summary>
297    public IEnumerable<HiveJob> GetAllHiveJobs() {
298      var jobs = new List<HiveJob>();
299      jobs.Add(this);
300      foreach (HiveJob child in this.ChildHiveJobs) {
301        jobs.AddRange(child.GetAllHiveJobs());
302      }
303      return jobs;
304    }
305
306    public HiveJob GetParentByJobId(Guid jobId) {
307      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
308        return this;
309      foreach (HiveJob child in this.childHiveJobs) {
310        HiveJob result = child.GetParentByJobId(jobId);
311        if (result != null)
312          return result;
313      }
314      return null;
315    }
316
317    /// <summary>
318    /// Searches for an HiveJob object with the correct jobId recursively
319    /// </summary>
320    public HiveJob GetHiveJobByJobId(Guid jobId) {
321      if (this.Job.Id == jobId) {
322        return this;
323      } else {
324        foreach (HiveJob child in this.ChildHiveJobs) {
325          HiveJob result = child.GetHiveJobByJobId(jobId);
326          if (result != null)
327            return result;
328        }
329      }
330      return null;
331    }
332
333    public void RemoveByJobId(Guid jobId) {
334      IEnumerable<HiveJob> jobs = ChildHiveJobs.Where(j => j.Job.Id == jobId).ToList(); // if Guid.Empty needs to be removed, there could be more than one with this jobId
335      foreach (HiveJob j in jobs) {
336        this.childHiveJobs.Remove(j);
337      }
338      foreach (HiveJob child in ChildHiveJobs) {
339        child.RemoveByJobId(jobId);
340      }
341    }
342
343    public IEnumerable<IItemTree<HiveJob>> GetChildItems() {
344      return this.childHiveJobs;
345    }
346
347    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
348
349    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> CollectionReset;
350    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
351      var handler = CollectionReset;
352      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
353    }
354
355    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsAdded;
356    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
357      var handler = ItemsAdded;
358      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
359    }
360
361    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsRemoved;
362    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
363      var handler = ItemsRemoved;
364      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
365    }
366
367    private static CollectionItemsChangedEventArgs<IItemTree<HiveJob>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
368      return new CollectionItemsChangedEventArgs<IItemTree<HiveJob>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
369    }
370    #endregion
371
372    public void Pause() {
373      if (this.Job.IsParentJob) {
374        foreach (var child in ChildHiveJobs) {
375          ServiceLocator.Instance.CallHiveService(s => s.PauseJob(child.job.Id));
376        }
377      } else {
378        ServiceLocator.Instance.CallHiveService(s => s.PauseJob(this.job.Id));
379      }
380    }
381
382    public void Stop() {
383      if (this.Job.IsParentJob) {
384        foreach (var child in ChildHiveJobs) {
385          ServiceLocator.Instance.CallHiveService(s => s.StopJob(child.job.Id));
386        }
387      } else {
388        ServiceLocator.Instance.CallHiveService(s => s.StopJob(this.job.Id));
389      }
390    }
391
392    public void Restart() {
393      ServiceLocator.Instance.CallHiveService(service => {
394        JobData jobData = new JobData();
395        jobData.JobId = this.job.Id;
396        jobData.Data = PersistenceUtil.Serialize(this.itemJob);
397        service.UpdateJobData(this.Job, jobData);
398        service.RestartJob(this.job.Id);
399        Job job = service.GetJob(this.job.Id);
400        this.job.LastJobDataUpdate = job.LastJobDataUpdate;
401      });
402    }
403
404    public ICollection<IItemTreeNodeAction<HiveJob>> Actions {
405      get {
406        return new List<IItemTreeNodeAction<HiveJob>>();
407      }
408    }
409
410    public virtual void IntegrateChild(ItemJob job, Guid childJobId) { }
411
412    /// <summary>
413    /// Delete ItemJob
414    /// </summary>
415    public void ClearData() {
416      this.ItemJob.Item = null;
417    }
418  }
419
420  [Item("Hive Job", "Represents a hive job.")]
421  [StorableClass]
422  public class HiveJob<T> : HiveJob where T : ItemJob {
423
424    public new T ItemJob {
425      get { return (T)base.ItemJob; }
426      internal set { base.ItemJob = value; }
427    }
428
429    #region Constructors and Cloning
430    public HiveJob() : base() { }
431    public HiveJob(T itemJob) : base(itemJob, true) { }
432    protected HiveJob(HiveJob original, Cloner cloner)
433      : base(original, cloner) {
434    }
435    public override IDeepCloneable Clone(Cloner cloner) {
436      return new HiveJob<T>(this, cloner);
437    }
438    #endregion
439  }
440}
Note: See TracBrowser for help on using the repository browser.