Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

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