Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

  • added semaphores to ensure an appdomain is never unloaded when the start method has not finished
  • HiveEngine uploading and downloading of jobs works and is displayed in the view
File size: 15.1 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          itemJobDownloaded = 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          OnJobItemChanged();
89          itemJobDownloaded = true;
90        }
91      }
92    }
93
94    // job downloaded since last status change
95    [Storable]
96    private bool itemJobDownloaded = false;
97    public bool ItemJobDownloaded {
98      get { return itemJobDownloaded; }
99    }
100
101    [Storable]
102    protected ItemList<HiveJob> childHiveJobs;
103    public virtual ReadOnlyItemList<HiveJob> ChildHiveJobs {
104      get { return childHiveJobs.AsReadOnly(); }
105    }
106
107    [Storable]
108    protected bool syncJobsWithOptimizers = true;
109
110    #region Constructors and Cloning
111    public HiveJob() {
112      this.Job = new Job() {
113        CoresNeeded = 1,
114        MemoryNeeded = 0
115      };
116      job.State = JobState.Offline;
117      this.childHiveJobs = new ItemList<HiveJob>();
118      syncJobsWithOptimizers = true;
119      RegisterChildHiveJobEvents();
120    }
121
122    public HiveJob(ItemJob itemJob, bool autoCreateChildHiveJobs)
123      : this() {
124      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
125      this.ItemJob = itemJob;
126      this.syncJobsWithOptimizers = true;
127    }
128
129    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs) {
130      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
131      this.Job = job;
132      try {
133        this.ItemJob = PersistenceUtil.Deserialize<ItemJob>(jobData.Data);
134      }
135      catch {
136        this.ItemJob = null;
137      }
138      this.childHiveJobs = new ItemList<HiveJob>();
139      this.syncJobsWithOptimizers = true;
140      RegisterChildHiveJobEvents();
141    }
142
143    protected HiveJob(HiveJob original, Cloner cloner)
144      : base(original, cloner) {
145      this.Job = cloner.Clone(original.job);
146      this.ItemJob = cloner.Clone(original.ItemJob);
147      this.childHiveJobs = cloner.Clone(original.childHiveJobs);
148      this.syncJobsWithOptimizers = original.syncJobsWithOptimizers;
149      this.itemJobDownloaded = original.itemJobDownloaded;
150    }
151    public override IDeepCloneable Clone(Cloner cloner) {
152      return new HiveJob(this, cloner);
153    }
154    #endregion
155
156    protected virtual void UpdateChildHiveJobs() { }
157
158    protected virtual void RegisterItemJobEvents() {
159      if (ItemJob != null) {
160        ItemJob.ComputeInParallelChanged += new EventHandler(JobItem_ComputeInParallelChanged);
161        ItemJob.ToStringChanged += new EventHandler(JobItem_ToStringChanged);
162      }
163    }
164    protected virtual void DergisterItemJobEvents() {
165      if (ItemJob != null) {
166        ItemJob.ComputeInParallelChanged -= new EventHandler(JobItem_ComputeInParallelChanged);
167        ItemJob.ToStringChanged -= new EventHandler(JobItem_ToStringChanged);
168      }
169    }
170
171    protected virtual void RegisterChildHiveJobEvents() {
172      this.childHiveJobs.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
173      this.childHiveJobs.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
174      this.childHiveJobs.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
175    }
176    protected virtual void DeregisterChildHiveJobEvents() {
177      this.childHiveJobs.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
178      this.childHiveJobs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
179      this.childHiveJobs.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
180    }
181
182    protected virtual void JobItem_ToStringChanged(object sender, EventArgs e) {
183      this.OnToStringChanged();
184    }
185
186    protected virtual void JobItem_ComputeInParallelChanged(object sender, EventArgs e) {
187      if (ItemJob != null && syncJobsWithOptimizers) {
188        this.UpdateChildHiveJobs();
189      }
190    }
191
192    public virtual void AddChildHiveJob(HiveJob hiveJob) {
193      this.childHiveJobs.Add(hiveJob);
194    }
195
196    public override string ToString() {
197      if (itemJob != null) {
198        return itemJob.ToString();
199      } else {
200        return base.ToString();
201      }
202    }
203
204    public virtual void UpdateFromLightweightJob(LightweightJob lightweightJob) {
205      if (lightweightJob != null) {
206        job.Id = lightweightJob.Id;
207        job.ParentJobId = lightweightJob.ParentJobId;
208        job.ExecutionTime = lightweightJob.ExecutionTime;
209        job.State = lightweightJob.State;
210        job.StateLog = new List<StateLog>(lightweightJob.StateLog);
211        job.Command = lightweightJob.Command;
212        job.LastJobDataUpdate = lightweightJob.LastJobDataUpdate;
213
214        OnJobStateChanged();
215        OnToStringChanged();
216        OnItemImageChanged();
217      }
218    }
219
220    /// <summary>
221    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
222    /// </summary>
223    /// <param name="withoutChildOptimizers">
224    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
225    /// </param>
226    public virtual JobData GetAsJobData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
227      plugins = new List<IPluginDescription>();
228      if (this.itemJob == null)
229        return null;
230
231      IEnumerable<Type> usedTypes;
232      byte[] jobByteArray = PersistenceUtil.Serialize(this.ItemJob, out usedTypes);
233
234      JobData jobData = new JobData() {
235        JobId = job.Id,
236        Data = jobByteArray
237      };
238
239      PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
240
241      return jobData;
242    }
243
244    #region Events
245    public event EventHandler JobChanged;
246    private void OnJobChanged() {
247      EventHandler handler = JobChanged;
248      if (handler != null) handler(this, EventArgs.Empty);
249    }
250
251    public event EventHandler JobStateChanged;
252    private void OnJobStateChanged() {
253      EventHandler handler = JobStateChanged;
254      if (handler != null) handler(this, EventArgs.Empty);
255    }
256
257    public event EventHandler JobItemChanged;
258    private void OnJobItemChanged() {
259      JobItem_ComputeInParallelChanged(this, EventArgs.Empty);
260      var handler = JobItemChanged;
261      if (handler != null) handler(this, EventArgs.Empty);
262    }
263
264    public event EventHandler IsFinishedOptimizerDownloadedChanged;
265    private void OnIsFinishedOptimizerDownloadedChanged() {
266      var handler = IsFinishedOptimizerDownloadedChanged;
267      if (handler != null) handler(this, EventArgs.Empty);
268    }
269
270    private void RegisterJobEvents() {
271      if (job != null)
272        job.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
273    }
274
275    private void DeregisterJobEvents() {
276      if (job != null)
277        job.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(job_PropertyChanged);
278    }
279
280    private void job_PropertyChanged(object sender, PropertyChangedEventArgs e) {
281      if (e.PropertyName == "State") {
282        itemJobDownloaded = false;
283      }
284    }
285    #endregion
286
287    /// <summary>
288    /// Returns a list of HiveJobs including this and all its child-jobs recursively
289    /// </summary>
290    public IEnumerable<HiveJob> GetAllHiveJobs() {
291      var jobs = new List<HiveJob>();
292      jobs.Add(this);
293      foreach (HiveJob child in this.ChildHiveJobs) {
294        jobs.AddRange(child.GetAllHiveJobs());
295      }
296      return jobs;
297    }
298
299    public HiveJob GetParentByJobId(Guid jobId) {
300      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
301        return this;
302      foreach (HiveJob child in this.childHiveJobs) {
303        HiveJob result = child.GetParentByJobId(jobId);
304        if (result != null)
305          return result;
306      }
307      return null;
308    }
309
310    /// <summary>
311    /// Searches for an HiveJob object with the correct jobId recursively
312    /// </summary>
313    public HiveJob GetHiveJobByJobId(Guid jobId) {
314      if (this.Job.Id == jobId) {
315        return this;
316      } else {
317        foreach (HiveJob child in this.ChildHiveJobs) {
318          HiveJob result = child.GetHiveJobByJobId(jobId);
319          if (result != null)
320            return result;
321        }
322      }
323      return null;
324    }
325
326    public void RemoveByJobId(Guid jobId) {
327      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
328      foreach (HiveJob j in jobs) {
329        this.childHiveJobs.Remove(j);
330      }
331      foreach (HiveJob child in ChildHiveJobs) {
332        child.RemoveByJobId(jobId);
333      }
334    }
335
336    public IEnumerable<IItemTree<HiveJob>> GetChildItems() {
337      return this.childHiveJobs;
338    }
339
340    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
341
342    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> CollectionReset;
343    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
344      var handler = CollectionReset;
345      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
346    }
347
348    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsAdded;
349    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
350      var handler = ItemsAdded;
351      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
352    }
353
354    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsRemoved;
355    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
356      var handler = ItemsRemoved;
357      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
358    }
359
360    private static CollectionItemsChangedEventArgs<IItemTree<HiveJob>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
361      return new CollectionItemsChangedEventArgs<IItemTree<HiveJob>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
362    }
363    #endregion
364
365    public void Pause() {
366      if (this.Job.IsParentJob) {
367        foreach (var child in ChildHiveJobs) {
368          ServiceLocator.Instance.CallHiveService(s => s.PauseJob(child.job.Id));
369        }
370      } else {
371        ServiceLocator.Instance.CallHiveService(s => s.PauseJob(this.job.Id));
372      }
373    }
374
375    public void Stop() {
376      if (this.Job.IsParentJob) {
377        foreach (var child in ChildHiveJobs) {
378          ServiceLocator.Instance.CallHiveService(s => s.StopJob(child.job.Id));
379        }
380      } else {
381        ServiceLocator.Instance.CallHiveService(s => s.StopJob(this.job.Id));
382      }
383    }
384
385    public void Restart() {
386      ServiceLocator.Instance.CallHiveService(service => {
387        JobData jobData = new JobData();
388        jobData.JobId = this.job.Id;
389        jobData.Data = PersistenceUtil.Serialize(this.itemJob);
390        service.UpdateJobData(this.Job, jobData);
391        service.RestartJob(this.job.Id);
392        Job job = service.GetJob(this.job.Id);
393        this.job.LastJobDataUpdate = job.LastJobDataUpdate;
394      });
395    }
396
397    public ICollection<IItemTreeNodeAction<HiveJob>> Actions {
398      get {
399        return new List<IItemTreeNodeAction<HiveJob>>();
400      }
401    }
402
403    public virtual void IntegrateChild(ItemJob job, Guid childJobId) { }
404  }
405
406  [Item("Hive Job", "Represents a hive job.")]
407  [StorableClass]
408  public class HiveJob<T> : HiveJob where T : ItemJob {
409
410    public new T ItemJob {
411      get { return (T)base.ItemJob; }
412      internal set { base.ItemJob = value; }
413    }
414
415    #region Constructors and Cloning
416    public HiveJob() : base() { }
417    public HiveJob(T itemJob) : base(itemJob, true) { }
418    protected HiveJob(HiveJob original, Cloner cloner)
419      : base(original, cloner) {
420    }
421    public override IDeepCloneable Clone(Cloner cloner) {
422      return new HiveJob<T>(this, cloner);
423    }
424    #endregion
425  }
426}
Note: See TracBrowser for help on using the repository browser.