Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJobClient.cs @ 5363

Last change on this file since 5363 was 5363, checked in by ascheibe, 13 years ago

#1233 adapt Hive to HL trunk

File size: 24.6 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.IO;
26using System.Linq;
27using HeuristicLab.Clients.Hive.Jobs;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Optimization;
32using HeuristicLab.PluginInfrastructure;
33using HeuristicLab.Services.Hive.Common.DataTransfer;
34
35namespace HeuristicLab.Clients.Hive {
36
37  [Item("Hive Job", "Represents a hive job.")]
38  public class HiveJob : Item {
39    private 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.JobState == JobState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
47          else if (job.JobState == JobState.WaitingForChildJobs) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
48          else if (job.JobState == JobState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
49          else if (job.JobState == JobState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
50          else if (job.JobState == JobState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
51          else if (job.JobState == JobState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
52          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
53        }
54      }
55    }
56
57    private 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    private OptimizerJob optimizerJob;
71    public OptimizerJob OptimizerJob {
72      get { return optimizerJob; }
73      private set {
74        if (optimizerJob != null && syncJobsWithOptimizers) {
75          this.childHiveJobs.Clear();
76        }
77        if (optimizerJob != value) {
78          DergisterOptimizerEvents();
79          optimizerJob = value;
80          if (optimizerJob.ExecutionState == ExecutionState.Stopped) {
81            IsFinishedOptimizerDownloaded = true;
82          }
83          RegisterOptimizerEvents();
84          OnOptimizerJobChanged();
85        }
86      }
87    }
88
89    private ItemList<HiveJob> childHiveJobs;
90    public ReadOnlyItemList<HiveJob> ChildHiveJobs {
91      get { return childHiveJobs.AsReadOnly(); }
92    }
93
94    private bool isFinishedOptimizerDownloaded;
95    public bool IsFinishedOptimizerDownloaded {
96      get { return isFinishedOptimizerDownloaded; }
97      set {
98        if (isFinishedOptimizerDownloaded != value) {
99          isFinishedOptimizerDownloaded = value;
100          OnIsFinishedOptimizerDownloadedChanged();
101        }
102      }
103    }
104
105    private bool syncJobsWithOptimizers = true;
106
107    public HiveJob() {
108      this.Job = new Job() {
109        JobState = JobState.Waiting,
110        DateCreated = DateTime.Now,
111        CoresNeeded = 1,
112        MemoryNeeded = 0
113      };
114      this.childHiveJobs = new ItemList<HiveJob>();
115      syncJobsWithOptimizers = true;
116    }
117
118    public HiveJob(Job jobDto)
119      : this() {
120      this.Job = jobDto;
121    }
122
123    public HiveJob(LightweightJob lightweightJob)
124      : this() {
125      UpdateFromLightweightJob(lightweightJob);
126    }
127
128    public HiveJob(OptimizerJob optimizerJob, bool autoCreateChildHiveJobs)
129      : this() {
130      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
131      this.OptimizerJob = optimizerJob;
132      this.syncJobsWithOptimizers = true;
133    }
134
135    public HiveJob(IOptimizer optimizer)
136      : this() {
137      this.OptimizerJob = new OptimizerJob(optimizer);
138    }
139
140    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs)
141      : this() {
142      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
143      this.Job = job;
144      try {
145        this.OptimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(jobData.Data);
146      }
147      catch {
148        this.OptimizerJob = null;
149      }
150      this.syncJobsWithOptimizers = true;
151    }
152
153    protected HiveJob(HiveJob original, Cloner cloner)
154      : base(original, cloner) {
155      this.Job = cloner.Clone(original.job);
156      this.OptimizerJob = cloner.Clone(original.OptimizerJob);
157    }
158    public override IDeepCloneable Clone(Cloner cloner) {
159      return new HiveJob(this, cloner);
160    }
161
162    /// <summary>
163    /// if this.Optimizer is an experiment
164    ///   Uses the child-optimizers of this.HiveJob and creates HiveJob-childs
165    /// if this.Optimizer is a batchrun
166    ///   Creates a number of child-jobs according to repetitions
167    /// </summary>
168    private void UpdateChildHiveJobs() {
169      if (Job != null && syncJobsWithOptimizers) {
170        if (OptimizerJob.Optimizer is Optimization.Experiment) {
171          Optimization.Experiment experiment = (Optimization.Experiment)OptimizerJob.Optimizer;
172          foreach (IOptimizer childOpt in experiment.Optimizers) {
173            this.childHiveJobs.Add(new HiveJob(childOpt));
174          }
175        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
176          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
177          if (batchRun.Optimizer != null) {
178            while (this.childHiveJobs.Count < batchRun.Repetitions) {
179              this.childHiveJobs.Add(new HiveJob(batchRun.Optimizer));
180            }
181            while (this.childHiveJobs.Count > batchRun.Repetitions) {
182              this.childHiveJobs.Remove(this.childHiveJobs.Last());
183            }
184          }
185        }
186      }
187    }
188
189    private void RegisterOptimizerEvents() {
190      if (OptimizerJob != null) {
191        if (OptimizerJob.Optimizer is Optimization.Experiment) {
192          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
193          experiment.Optimizers.ItemsAdded += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
194          experiment.Optimizers.ItemsReplaced += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
195          experiment.Optimizers.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
196          experiment.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
197        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
198          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
199          batchRun.RepetitionsChanged += new EventHandler(batchRun_RepetitionsChanged);
200          batchRun.OptimizerChanged += new EventHandler(batchRun_OptimizerChanged);
201        }
202        OptimizerJob.ComputeInParallelChanged += new EventHandler(OptimizerJob_ComputeInParallelChanged);
203        OptimizerJob.ToStringChanged += new EventHandler(OptimizerJob_ToStringChanged);
204      }
205    }
206    private void DergisterOptimizerEvents() {
207      if (OptimizerJob != null) {
208        if (OptimizerJob.Optimizer is Optimization.Experiment) {
209          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
210          experiment.Optimizers.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
211          experiment.Optimizers.ItemsReplaced -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
212          experiment.Optimizers.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
213          experiment.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
214        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
215          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
216          batchRun.RepetitionsChanged -= new EventHandler(batchRun_RepetitionsChanged);
217          batchRun.OptimizerChanged -= new EventHandler(batchRun_OptimizerChanged);
218        }
219        OptimizerJob.ComputeInParallelChanged -= new EventHandler(OptimizerJob_ComputeInParallelChanged);
220        OptimizerJob.ToStringChanged -= new EventHandler(OptimizerJob_ToStringChanged);
221      }
222    }
223
224    void batchRun_OptimizerChanged(object sender, EventArgs e) {
225      if (syncJobsWithOptimizers) {
226        this.childHiveJobs.Clear();
227        UpdateChildHiveJobs();
228      }
229    }
230
231    void batchRun_RepetitionsChanged(object sender, EventArgs e) {
232      if (syncJobsWithOptimizers) {
233        UpdateChildHiveJobs();
234      }
235    }
236
237    void OptimizerJob_ToStringChanged(object sender, EventArgs e) {
238      this.OnToStringChanged();
239    }
240
241    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
242      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
243        foreach (var item in e.Items) {
244          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
245            this.childHiveJobs.Add(new HiveJob(item.Value));
246          }
247        }
248      }
249    }
250    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
251      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
252        foreach (var item in e.OldItems) {
253          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
254        }
255        foreach (var item in e.Items) {
256          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
257            this.childHiveJobs.Add(new HiveJob(item.Value));
258          }
259        }
260      }
261    }
262    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
263      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
264        foreach (var item in e.Items) {
265          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
266        }
267      }
268    }
269    void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
270      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
271        foreach (var item in e.Items) {
272          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
273        }
274      }
275    }
276
277    void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
278      if (OptimizerJob != null && syncJobsWithOptimizers) {
279        if (OptimizerJob.ComputeInParallel) {
280          // child-hive jobs are not yet created, so create them according to the child-optimizers
281          this.UpdateChildHiveJobs();
282        } else {
283          // child-hive jobs need to be deleted
284          this.childHiveJobs.Clear();
285        }
286      }
287    }
288
289    public void AddChildHiveJob(HiveJob hiveJob) {
290      this.childHiveJobs.Add(hiveJob);
291      syncJobsWithOptimizers = false;
292      if (this.OptimizerJob != null && hiveJob.OptimizerJob != null) {
293        if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
294          if (!this.OptimizerJob.OptimizerAsExperiment.Optimizers.Contains(hiveJob.OptimizerJob.Optimizer)) {
295            UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, hiveJob.OptimizerJob);
296          }
297        } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
298          UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, hiveJob.OptimizerJob);
299        }
300      }
301      syncJobsWithOptimizers = true;
302    }
303
304    /// <summary>
305    /// if this.Optimizer is Experiment
306    ///   replace the child-optimizer in the experiment
307    /// if this.Optimizer is BatchRun
308    ///   add the runs from the optimizerJob to the batchrun and replace the Optimizer
309    /// </summary>
310    public void UpdateChildOptimizer(OptimizerJob optimizerJob, Guid childJobId) {
311      syncJobsWithOptimizers = false; // don't sync with optimizers during this method
312      bool childIsFinishedOptimizerDownloaded = false;
313
314      if (this.OptimizerJob != null && this.OptimizerJob.Optimizer != null) {
315        if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
316          UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, optimizerJob);
317          childIsFinishedOptimizerDownloaded = true;
318        } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
319          UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, optimizerJob);
320          if (this.OptimizerJob.OptimizerAsBatchRun.Repetitions == this.OptimizerJob.Optimizer.Runs.Count) {
321            childIsFinishedOptimizerDownloaded = true;
322          }
323        } else {
324          childIsFinishedOptimizerDownloaded = optimizerJob.Optimizer.ExecutionState == ExecutionState.Stopped;
325        }
326      }
327
328      HiveJob child = this.ChildHiveJobs.Single(j => j.Job.Id == childJobId);
329      if (!optimizerJob.ComputeInParallel) {
330        child.syncJobsWithOptimizers = false;
331        child.OptimizerJob = optimizerJob;
332        child.syncJobsWithOptimizers = true;
333      }
334      if (childIsFinishedOptimizerDownloaded) {
335        child.IsFinishedOptimizerDownloaded = true;
336      }
337      syncJobsWithOptimizers = true;
338    }
339
340    /// <summary>
341    /// Adds the runs from the optimizerJob to the batchrun and replaces the Optimizer
342    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
343    /// </summary>
344    private void UpdateOptimizerInBatchRun(BatchRun batchRun, OptimizerJob optimizerJob) {
345      if (batchRun.Optimizer == null) {
346        batchRun.Optimizer = (IOptimizer)optimizerJob.Optimizer; // only set the first optimizer as Optimizer. if every time the Optimizer would be set, the runs would be cleared each time
347      }
348      foreach (IRun run in optimizerJob.Optimizer.Runs) {
349        if (!batchRun.Runs.Contains(run))
350          batchRun.Runs.Add(run);
351      }
352    }
353
354    /// <summary>
355    /// replace the child-optimizer in the experiment
356    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
357    /// </summary>
358    private void UpdateOptimizerInExperiment(Optimization.Experiment experiment, OptimizerJob optimizerJob) {
359      if (optimizerJob.IndexInParentOptimizerList < 0)
360        throw new IndexOutOfRangeException("IndexInParentOptimizerList must be equal or greater than zero! The Job is invalid and the optimizer-tree cannot be reassembled.");
361
362      while (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList) {
363        experiment.Optimizers.Add(new UserDefinedAlgorithm("Placeholder")); // add dummy-entries to Optimizers so that its possible to insert the optimizerJob at the correct position
364      }
365      if (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList + 1) {
366        experiment.Optimizers.Add(optimizerJob.Optimizer);
367      } else {
368        // if ComputeInParallel==true, don't replace the optimizer (except it is still a Placeholder)
369        // this is because Jobs with ComputeInParallel get submitted to hive with their child-optimizers deleted
370        if (!optimizerJob.ComputeInParallel || experiment.Optimizers[optimizerJob.IndexInParentOptimizerList].Name == "Placeholder") {
371          experiment.Optimizers[optimizerJob.IndexInParentOptimizerList] = optimizerJob.Optimizer;
372        }
373      }
374    }
375
376    /// <summary>
377    /// Sets the IndexInParentOptimizerList property of the OptimizerJob
378    /// according to the position in the OptimizerList of the parentHiveJob.Job
379    /// Recursively updates all the child-jobs as well
380    /// </summary>
381    internal void SetIndexInParentOptimizerList(HiveJob parentHiveJob) {
382      if (parentHiveJob != null) {
383        if (parentHiveJob.OptimizerJob.Optimizer is Optimization.Experiment) {
384          this.OptimizerJob.IndexInParentOptimizerList = parentHiveJob.OptimizerJob.OptimizerAsExperiment.Optimizers.IndexOf(this.OptimizerJob.Optimizer);
385        } else if (parentHiveJob.OptimizerJob.Optimizer is Optimization.BatchRun) {
386          this.OptimizerJob.IndexInParentOptimizerList = 0;
387        } else {
388          throw new NotSupportedException("Only Experiment and BatchRuns are supported");
389        }
390      }
391      foreach (HiveJob child in childHiveJobs) {
392        child.SetIndexInParentOptimizerList(this);
393      }
394    }
395
396    public override string ToString() {
397      if (optimizerJob != null) {
398        return optimizerJob.ToString();
399      } else {
400        return base.ToString();
401      }
402    }
403
404    public void UpdateFromLightweightJob(LightweightJob lightweightJob) {
405      if (lightweightJob != null) {
406        job.Id = lightweightJob.Id;
407        job.DateCreated = lightweightJob.DateCreated;
408        job.DateCalculated = lightweightJob.DateCalculated;
409        job.DateFinished = lightweightJob.DateFinished;
410        job.Exception = lightweightJob.Exception;
411        job.Id = lightweightJob.Id;
412        job.ExecutionTime = lightweightJob.ExecutionTime;
413        job.JobState = lightweightJob.JobState;
414        // what about parentJob
415        OnJobStateChanged();
416        OnToStringChanged();
417        OnItemImageChanged();
418      }
419    }
420
421    /// <summary>
422    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
423    /// </summary>
424    /// <param name="withoutChildOptimizers">
425    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
426    /// </param>
427    public JobData GetAsJobData(bool withoutChildOptimizers) {
428      if (this.optimizerJob == null || this.optimizerJob.Optimizer == null)
429        return null;
430
431      byte[] jobByteArray;
432      if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.Experiment) {
433        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone(); // use a cloned job, so that the childHiveJob don't get confused
434        clonedJob.OptimizerAsExperiment.Optimizers.Clear();
435        jobByteArray = PersistenceUtil.Serialize(clonedJob);
436      } else if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.BatchRun) {
437        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone();
438        clonedJob.OptimizerAsBatchRun.Optimizer = null;
439        jobByteArray = PersistenceUtil.Serialize(clonedJob);
440      } else if (this.OptimizerJob.Optimizer is IAlgorithm) {
441        ((IAlgorithm)this.OptimizerJob.Optimizer).StoreAlgorithmInEachRun = false; // avoid storing the algorithm in runs to reduce size
442        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob);
443      } else {
444        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob);
445      }
446
447      UpdateRequiredPlugins();
448
449      JobData jobData = new JobData() {
450        JobId = job.Id,
451        Data = jobByteArray
452      };
453
454      return jobData;
455    }
456
457    /// <summary>
458    /// find out which which plugins are needed for the given object
459    /// </summary>
460    private void UpdateRequiredPlugins() {
461      List<Guid> pluginList = new List<Guid>();
462
463      IEnumerable<IPluginDescription> neededPlugins = ApplicationManager.Manager.Plugins; //HivePluginInfoDto.FindPluginsNeeded(optimizerJob.GetType());
464      using (var service = ServiceLocator.Instance.GetService()) {
465        IEnumerable<Plugin> availablePlugins = service.Obj.GetPlugins();
466        foreach (IPluginDescription neededPlugin in neededPlugins) {
467          Plugin found = availablePlugins.Where(availablePlugin => availablePlugin.Name == neededPlugin.Name && availablePlugin.Version.Major == neededPlugin.Version.Major && availablePlugin.Version.Minor == neededPlugin.Version.Minor && availablePlugin.Version.Revision == neededPlugin.Version.Revision && availablePlugin.Version.MinorRevision == neededPlugin.Version.MinorRevision).SingleOrDefault();
468          if (found != null) {
469            pluginList.Add(found.Id);
470          } else {
471            Plugin p = new Plugin() { Name = neededPlugin.Name, Version = neededPlugin.Version };
472            List<PluginData> pluginDatas = new List<PluginData>();
473
474            foreach (IPluginFile pf in neededPlugin.Files) {
475              PluginData pluginData = new PluginData();
476
477              pluginData.Data = File.ReadAllBytes(pf.Name);
478              pluginDatas.Add(pluginData);
479            }
480            pluginList.Add(service.Obj.AddPlugin(p, pluginDatas));
481          }
482        }
483      }
484      this.Job.PluginsNeededIds = pluginList;
485    }
486
487    #region Events
488    public event EventHandler JobChanged;
489    private void OnJobChanged() {
490      LogMessage("JobChanged");
491      EventHandler handler = JobChanged;
492      if (handler != null) handler(this, EventArgs.Empty);
493    }
494
495    public event EventHandler JobStateChanged;
496    private void OnJobStateChanged() {
497      LogMessage("JobStateChanged (State: " + this.Job.JobState + ", ExecutionTime: " + this.Job.ExecutionTime.ToString() + ")");
498      EventHandler handler = JobStateChanged;
499      if (handler != null) handler(this, EventArgs.Empty);
500    }
501
502    public event EventHandler OptimizerJobChanged;
503    private void OnOptimizerJobChanged() {
504      OptimizerJob_ComputeInParallelChanged(this, EventArgs.Empty);
505      var handler = JobChanged;
506      if (handler != null) handler(this, EventArgs.Empty);
507    }
508
509    public event EventHandler IsFinishedOptimizerDownloadedChanged;
510    private void OnIsFinishedOptimizerDownloadedChanged() {
511      var handler = IsFinishedOptimizerDownloadedChanged;
512      if (handler != null) handler(this, EventArgs.Empty);
513    }
514    #endregion
515
516    public void LogMessage(string message) {
517      lock (locker) {
518        if (optimizerJob != null) {
519          optimizerJob.Log.LogMessage(message);
520        }
521      }
522    }
523
524    /// <summary>
525    /// Returns a list of HiveJobs including this and all its child-jobs recursively
526    /// </summary>
527    public IEnumerable<HiveJob> GetAllHiveJobs() {
528      List<HiveJob> jobs = new List<HiveJob>();
529      jobs.Add(this);
530      foreach (HiveJob child in this.ChildHiveJobs) {
531        jobs.AddRange(child.GetAllHiveJobs());
532      }
533      return jobs;
534    }
535
536    public HiveJob GetParentByJobId(Guid jobId) {
537      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
538        return this;
539      foreach (HiveJob child in this.childHiveJobs) {
540        HiveJob result = child.GetParentByJobId(jobId);
541        if (result != null)
542          return result;
543      }
544      return null;
545    }
546
547
548    public HiveJob GetChildByOptimizerJob(OptimizerJob optimizerJob) {
549      foreach (var child in ChildHiveJobs) {
550        if (child.OptimizerJob == optimizerJob)
551          return child;
552      }
553      return null;
554    }
555
556
557    public HiveJob GetChildByOptimizer(IOptimizer optimizer) {
558      foreach (var child in ChildHiveJobs) {
559        if (child.OptimizerJob.Optimizer == optimizer)
560          return child;
561      }
562      return null;
563    }
564
565    /// <summary>
566    /// Searches for an HiveJob object with the correct jobId recursively
567    /// </summary>
568    public HiveJob GetHiveJobByJobId(Guid jobId) {
569      if (this.Job.Id == jobId) {
570        return this;
571      } else {
572        foreach (HiveJob child in this.ChildHiveJobs) {
573          HiveJob result = child.GetHiveJobByJobId(jobId);
574          if (result != null)
575            return result;
576        }
577      }
578      return null;
579    }
580
581
582    public void RemoveByJobId(Guid jobId) {
583      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
584      foreach (HiveJob j in jobs) {
585        this.childHiveJobs.Remove(j);
586      }
587      foreach (HiveJob child in ChildHiveJobs) {
588        child.RemoveByJobId(jobId);
589      }
590    }
591
592  }
593}
Note: See TracBrowser for help on using the repository browser.