Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobClient.cs @ 4905

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

#1233

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