Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.Hive.ExperimentManager/3.3/HiveJob.cs @ 5048

Last change on this file since 5048 was 4810, checked in by cneumuel, 14 years ago

#1260

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