Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

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