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

Last change on this file since 6033 was 6033, checked in by cneumuel, 9 years ago

#1233

  • created baseclass for jobs (ItemJob) which derives OperatorJobs and EngineJobs
  • created special view for OptimizerJobs which derives from a more general view
  • removed logic from domain class HiveExperiment and moved it into RefreshableHiveExperiment
  • improved ItemTreeView
  • corrected plugin dependencies
  • fixed bug in database trigger when deleting HiveExperiments
  • added delete cascade for Plugin and PluginData
  • lots of fixes
File size: 13.2 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.Drawing;
25using System.Linq;
26using HeuristicLab.Collections;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Hive;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.PluginInfrastructure;
32
33namespace HeuristicLab.Clients.Hive {
34
35  [Item("Hive Job", "Represents a hive job.")]
36  [StorableClass]
37  public class HiveJob : NamedItem, IItemTree<HiveJob> {
38    protected static object locker = new object();
39
40    public override Image ItemImage {
41      get {
42        if (job.Id == Guid.Empty) { // not yet uploaded
43          return HeuristicLab.Common.Resources.VSImageLibrary.Event;
44        } else {
45          if (job.State == JobState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
46          else if (job.State == JobState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
47          else if (job.State == JobState.Transferring) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
48          else if (job.State == JobState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
49          else if (job.State == JobState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
50          else if (job.State == JobState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
51          else if (job.State == JobState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
52          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
53        }
54      }
55    }
56
57    protected Job job;
58    public Job Job {
59      get { return job; }
60      set {
61        if (job != value) {
62          job = value;
63          OnJobChanged();
64          OnToStringChanged();
65          OnItemImageChanged();
66        }
67      }
68    }
69
70    [Storable]
71    protected ItemJob jobItem;
72    public ItemJob JobItem {
73      get { return jobItem; }
74      internal set {
75        if (jobItem != null && syncJobsWithOptimizers) {
76          this.childHiveJobs.Clear();
77        }
78        if (jobItem != value) {
79          DergisterJobItemsEvents();
80          jobItem = value;
81          RegisterJobItemEvents();
82          OnJobItemChanged();
83        }
84      }
85    }
86
87    [Storable]
88    protected ItemList<HiveJob> childHiveJobs;
89    public virtual ReadOnlyItemList<HiveJob> ChildHiveJobs {
90      get { return childHiveJobs.AsReadOnly(); }
91    }
92
93    [Storable]
94    protected bool syncJobsWithOptimizers = true;
95
96    #region Constructors and Cloning
97    public HiveJob() {
98      this.Job = new Job() {
99        CoresNeeded = 1,
100        MemoryNeeded = 0
101      };
102      job.State = JobState.Offline;
103      this.childHiveJobs = new ItemList<HiveJob>();
104      syncJobsWithOptimizers = true;
105      RegisterChildHiveJobEvents();
106    }
107
108    public HiveJob(ItemJob jobItem, bool autoCreateChildHiveJobs)
109      : this() {
110      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
111      this.JobItem = jobItem;
112      this.syncJobsWithOptimizers = true;
113    }
114
115    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs) {
116      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
117      this.Job = job;
118      try {
119        this.JobItem = PersistenceUtil.Deserialize<ItemJob>(jobData.Data);
120      }
121      catch {
122        this.JobItem = null;
123      }
124      this.childHiveJobs = new ItemList<HiveJob>();
125      this.syncJobsWithOptimizers = true;
126      RegisterChildHiveJobEvents();
127    }
128
129    protected HiveJob(HiveJob original, Cloner cloner)
130      : base(original, cloner) {
131      this.Job = cloner.Clone(original.job);
132      this.JobItem = cloner.Clone(original.JobItem);
133      this.childHiveJobs = cloner.Clone(original.childHiveJobs);
134      this.syncJobsWithOptimizers = original.syncJobsWithOptimizers;
135    }
136    public override IDeepCloneable Clone(Cloner cloner) {
137      return new HiveJob(this, cloner);
138    }
139    #endregion
140
141    protected virtual void UpdateChildHiveJobs() { }
142
143    protected virtual void RegisterJobItemEvents() {
144      if (JobItem != null) {
145        JobItem.ComputeInParallelChanged += new EventHandler(JobItem_ComputeInParallelChanged);
146        JobItem.ToStringChanged += new EventHandler(JobItem_ToStringChanged);
147      }
148    }
149    protected virtual void DergisterJobItemsEvents() {
150      if (JobItem != null) {
151        JobItem.ComputeInParallelChanged -= new EventHandler(JobItem_ComputeInParallelChanged);
152        JobItem.ToStringChanged -= new EventHandler(JobItem_ToStringChanged);
153      }
154    }
155
156    protected virtual void RegisterChildHiveJobEvents() {
157      this.childHiveJobs.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
158      this.childHiveJobs.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
159      this.childHiveJobs.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
160    }
161    protected virtual void DeregisterChildHiveJobEvents() {
162      this.childHiveJobs.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
163      this.childHiveJobs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
164      this.childHiveJobs.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
165    }
166
167    protected virtual void JobItem_ToStringChanged(object sender, EventArgs e) {
168      this.OnToStringChanged();
169    }
170   
171    protected virtual void JobItem_ComputeInParallelChanged(object sender, EventArgs e) {
172      if (JobItem != null && syncJobsWithOptimizers) {
173        this.UpdateChildHiveJobs();
174      }
175    }
176
177    public virtual void AddChildHiveJob(HiveJob hiveJob) {
178      this.childHiveJobs.Add(hiveJob);
179    }
180
181    public override string ToString() {
182      if (jobItem != null) {
183        return jobItem.ToString();
184      } else {
185        return base.ToString();
186      }
187    }
188
189    public virtual void UpdateFromLightweightJob(LightweightJob lightweightJob) {
190      if (lightweightJob != null) {
191        job.Id = lightweightJob.Id;
192        job.ParentJobId = lightweightJob.ParentJobId;
193        job.ExecutionTime = lightweightJob.ExecutionTime;
194        job.State = lightweightJob.State;
195        job.StateLog = new List<StateLog>(lightweightJob.StateLog);
196        job.Command = lightweightJob.Command;
197        job.LastJobDataUpdate = lightweightJob.LastJobDataUpdate;
198       
199        OnJobStateChanged();
200        OnToStringChanged();
201        OnItemImageChanged();
202      }
203    }
204
205    /// <summary>
206    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
207    /// </summary>
208    /// <param name="withoutChildOptimizers">
209    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
210    /// </param>
211    public virtual JobData GetAsJobData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
212      plugins = null;
213      return null;
214    }
215
216    #region Events
217    public event EventHandler JobChanged;
218    private void OnJobChanged() {
219      EventHandler handler = JobChanged;
220      if (handler != null) handler(this, EventArgs.Empty);
221    }
222
223    public event EventHandler JobStateChanged;
224    private void OnJobStateChanged() {
225      EventHandler handler = JobStateChanged;
226      if (handler != null) handler(this, EventArgs.Empty);
227    }
228
229    public event EventHandler JobItemChanged;
230    private void OnJobItemChanged() {
231      JobItem_ComputeInParallelChanged(this, EventArgs.Empty);
232      var handler = JobItemChanged;
233      if (handler != null) handler(this, EventArgs.Empty);
234    }
235
236    public event EventHandler IsFinishedOptimizerDownloadedChanged;
237    private void OnIsFinishedOptimizerDownloadedChanged() {
238      var handler = IsFinishedOptimizerDownloadedChanged;
239      if (handler != null) handler(this, EventArgs.Empty);
240    }
241    #endregion
242   
243    /// <summary>
244    /// Returns a list of HiveJobs including this and all its child-jobs recursively
245    /// </summary>
246    public IEnumerable<HiveJob> GetAllHiveJobs() {
247      var jobs = new List<HiveJob>();
248      jobs.Add(this);
249      foreach (HiveJob child in this.ChildHiveJobs) {
250        jobs.AddRange(child.GetAllHiveJobs());
251      }
252      return jobs;
253    }
254
255    public HiveJob GetParentByJobId(Guid jobId) {
256      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
257        return this;
258      foreach (HiveJob child in this.childHiveJobs) {
259        HiveJob result = child.GetParentByJobId(jobId);
260        if (result != null)
261          return result;
262      }
263      return null;
264    }
265
266    /// <summary>
267    /// Searches for an HiveJob object with the correct jobId recursively
268    /// </summary>
269    public HiveJob GetHiveJobByJobId(Guid jobId) {
270      if (this.Job.Id == jobId) {
271        return this;
272      } else {
273        foreach (HiveJob child in this.ChildHiveJobs) {
274          HiveJob result = child.GetHiveJobByJobId(jobId);
275          if (result != null)
276            return result;
277        }
278      }
279      return null;
280    }
281
282    public void RemoveByJobId(Guid jobId) {
283      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
284      foreach (HiveJob j in jobs) {
285        this.childHiveJobs.Remove(j);
286      }
287      foreach (HiveJob child in ChildHiveJobs) {
288        child.RemoveByJobId(jobId);
289      }
290    }
291
292    public IEnumerable<IItemTree<HiveJob>> GetChildItems() {
293      return this.childHiveJobs;
294    }
295
296    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
297
298    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> CollectionReset;
299    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
300      var handler = CollectionReset;
301      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
302    }
303
304    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsAdded;
305    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
306      var handler = ItemsAdded;
307      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
308    }
309
310    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsRemoved;
311    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
312      var handler = ItemsRemoved;
313      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
314    }
315
316    private static CollectionItemsChangedEventArgs<IItemTree<HiveJob>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
317      return new CollectionItemsChangedEventArgs<IItemTree<HiveJob>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
318    }
319    #endregion
320
321    public void Pause() {
322      ServiceLocator.Instance.CallHiveService(s => s.PauseJob(this.job.Id));
323    }
324
325    public void Stop() {
326      ServiceLocator.Instance.CallHiveService(s => s.StopJob(this.job.Id));
327    }
328
329    public void Restart() {
330      ServiceLocator.Instance.CallHiveService(service => {
331        JobData jobData = new JobData();
332        jobData.JobId = this.job.Id;
333        jobData.Data = PersistenceUtil.Serialize(this.jobItem);
334        service.UpdateJobData(this.Job, jobData);
335        service.RestartJob(this.job.Id);
336        Job job = service.GetJob(this.job.Id);
337        this.job.LastJobDataUpdate = job.LastJobDataUpdate;
338      });
339    }
340   
341    public ICollection<IItemTreeNodeAction<HiveJob>> Actions {
342      get {
343        return new List<IItemTreeNodeAction<HiveJob>>();
344      }
345    }
346  }
347
348  [Item("Hive Job", "Represents a hive job.")]
349  [StorableClass]
350  public class HiveJob<T> : HiveJob where T : ItemJob {
351
352    public new T JobItem {
353      get { return (T)base.JobItem; }
354      internal set { base.JobItem = value; }
355    }
356
357    #region Constructors and Cloning
358    public HiveJob() : base() { }
359    protected HiveJob(HiveJob original, Cloner cloner)
360      : base(original, cloner) {
361    }
362    public override IDeepCloneable Clone(Cloner cloner) {
363      return new HiveJob<T>(this, cloner);
364    }
365    #endregion
366  }
367}
Note: See TracBrowser for help on using the repository browser.