Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/HiveJob.cs @ 6381

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

#1233

  • locking for childHiveJobs in OptimizerHiveJob avoid multi threaded access issues
  • added IsPrivileged to gui
  • minor changes
File size: 16.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using System.Threading;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33
34namespace HeuristicLab.Clients.Hive {
35
36  [Item("Hive Job", "Represents a hive job.")]
37  [StorableClass]
38  public class HiveJob : NamedItem, IItemTree<HiveJob> {
39    protected static object locker = new object();
40    protected ReaderWriterLockSlim childHiveJobsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
41
42    public override Image ItemImage {
43      get {
44        if (job.Id == Guid.Empty) { // not yet uploaded
45          return HeuristicLab.Common.Resources.VSImageLibrary.Event;
46        } else {
47          if (job.State == JobState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
48          else if (job.State == JobState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
49          else if (job.State == JobState.Transferring) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
50          else if (job.State == JobState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
51          else if (job.State == JobState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
52          else if (job.State == JobState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
53          else if (job.State == JobState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
54          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
55        }
56      }
57    }
58
59    [Storable]
60    protected Job job;
61    public Job Job {
62      get { return job; }
63      set {
64        if (job != value) {
65          DeregisterJobEvents();
66          job = value;
67          RegisterJobEvents();
68          IsFinishedJobDownloaded = false;
69          OnJobChanged();
70          OnToStringChanged();
71          OnItemImageChanged();
72        }
73
74      }
75    }
76
77    [Storable]
78    protected ItemJob itemJob;
79    public ItemJob ItemJob {
80      get { return itemJob; }
81      set {
82        if (itemJob != null && syncJobsWithOptimizers) {
83          this.childHiveJobs.Clear();
84        }
85        if (itemJob != value) {
86          DergisterItemJobEvents();
87          itemJob = value;
88          RegisterItemJobEvents();
89          OnItemJobChanged();
90          IsFinishedJobDownloaded = true;
91        }
92      }
93    }
94
95    // job downloaded since last status change
96    [Storable]
97    private bool isFinishedJobDownloaded = false;
98    public bool IsFinishedJobDownloaded {
99      get { return isFinishedJobDownloaded; }
100      set {
101        if (value != isFinishedJobDownloaded) {
102          this.isFinishedJobDownloaded = value;
103          OnIsFinishedJobDownloadedChanged();
104        }
105      }
106    }
107
108    public bool IsDownloading { get; set; }
109
110    [Storable]
111    protected ItemList<HiveJob> childHiveJobs;
112    public virtual ReadOnlyItemList<HiveJob> ChildHiveJobs {
113      get {
114        childHiveJobsLock.EnterReadLock();
115        try {
116          return childHiveJobs.AsReadOnly();
117        }
118        finally { childHiveJobsLock.ExitReadLock(); }
119      }
120    }
121
122    [Storable]
123    protected bool syncJobsWithOptimizers = true;
124
125    #region Constructors and Cloning
126    public HiveJob() {
127      this.Job = new Job() { CoresNeeded = 1, MemoryNeeded = 0 };
128      job.State = JobState.Offline;
129      this.childHiveJobs = new ItemList<HiveJob>();
130      syncJobsWithOptimizers = true;
131      RegisterChildHiveJobEvents();
132    }
133
134    public HiveJob(ItemJob itemJob, bool autoCreateChildHiveJobs)
135      : this() {
136      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
137      this.ItemJob = itemJob;
138      this.syncJobsWithOptimizers = true;
139    }
140
141    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs) {
142      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
143      this.Job = job;
144      try {
145        this.ItemJob = PersistenceUtil.Deserialize<ItemJob>(jobData.Data);
146      }
147      catch {
148        this.ItemJob = null;
149      }
150      this.childHiveJobs = new ItemList<HiveJob>();
151      this.syncJobsWithOptimizers = true;
152      RegisterChildHiveJobEvents();
153    }
154
155    protected HiveJob(HiveJob original, Cloner cloner)
156      : base(original, cloner) {
157      this.Job = cloner.Clone(original.job);
158      this.ItemJob = cloner.Clone(original.ItemJob);
159      original.childHiveJobsLock.EnterReadLock();
160      try {
161        this.childHiveJobs = cloner.Clone(original.childHiveJobs);
162      }
163      finally { original.childHiveJobsLock.ExitReadLock(); }
164      this.syncJobsWithOptimizers = original.syncJobsWithOptimizers;
165      this.isFinishedJobDownloaded = original.isFinishedJobDownloaded;
166    }
167    public override IDeepCloneable Clone(Cloner cloner) {
168      return new HiveJob(this, cloner);
169    }
170    #endregion
171
172    protected virtual void UpdateChildHiveJobs() { }
173
174    protected virtual void RegisterItemJobEvents() {
175      if (ItemJob != null) {
176        ItemJob.ComputeInParallelChanged += new EventHandler(ItemJob_ComputeInParallelChanged);
177        ItemJob.ToStringChanged += new EventHandler(ItemJob_ToStringChanged);
178      }
179    }
180    protected virtual void DergisterItemJobEvents() {
181      if (ItemJob != null) {
182        ItemJob.ComputeInParallelChanged -= new EventHandler(ItemJob_ComputeInParallelChanged);
183        ItemJob.ToStringChanged -= new EventHandler(ItemJob_ToStringChanged);
184      }
185    }
186
187    protected virtual void RegisterChildHiveJobEvents() {
188      this.childHiveJobs.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
189      this.childHiveJobs.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
190      this.childHiveJobs.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
191    }
192    protected virtual void DeregisterChildHiveJobEvents() {
193      this.childHiveJobs.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
194      this.childHiveJobs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
195      this.childHiveJobs.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
196    }
197
198    protected virtual void ItemJob_ToStringChanged(object sender, EventArgs e) {
199      this.OnToStringChanged();
200    }
201
202    protected virtual void ItemJob_ComputeInParallelChanged(object sender, EventArgs e) {
203      if (ItemJob != null && syncJobsWithOptimizers) {
204        this.UpdateChildHiveJobs();
205      }
206    }
207
208    public virtual void AddChildHiveJob(HiveJob hiveJob) {
209      childHiveJobsLock.EnterWriteLock();
210      try {
211        this.childHiveJobs.Add(hiveJob);
212      }
213      finally { childHiveJobsLock.ExitWriteLock(); }
214    }
215
216    public override string ToString() {
217      if (itemJob != null && itemJob.Item != null) {
218        return itemJob.ToString();
219      } else {
220        return Job.Id.ToString();
221      }
222    }
223
224    public virtual void UpdateFromLightweightJob(LightweightJob lightweightJob) {
225      if (lightweightJob != null) {
226        job.Id = lightweightJob.Id;
227        job.ParentJobId = lightweightJob.ParentJobId;
228        job.ExecutionTime = lightweightJob.ExecutionTime;
229        job.State = lightweightJob.State;
230        job.StateLog = new List<StateLog>(lightweightJob.StateLog);
231        job.Command = lightweightJob.Command;
232
233        OnJobStateChanged();
234        OnToStringChanged();
235        OnItemImageChanged();
236      }
237    }
238
239    /// <summary>
240    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
241    /// </summary>
242    /// <param name="withoutChildOptimizers">
243    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
244    /// </param>
245    public virtual JobData GetAsJobData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
246      plugins = new List<IPluginDescription>();
247      if (this.itemJob == null)
248        return null;
249
250      IEnumerable<Type> usedTypes;
251      byte[] jobByteArray = PersistenceUtil.Serialize(this.ItemJob, out usedTypes);
252      JobData jobData = new JobData() { JobId = job.Id, Data = jobByteArray };
253      PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
254      return jobData;
255    }
256
257    #region Events
258    public event EventHandler JobChanged;
259    private void OnJobChanged() {
260      EventHandler handler = JobChanged;
261      if (handler != null) handler(this, EventArgs.Empty);
262    }
263
264    public event EventHandler JobStateChanged;
265    private void OnJobStateChanged() {
266      EventHandler handler = JobStateChanged;
267      if (handler != null) handler(this, EventArgs.Empty);
268    }
269
270    public event EventHandler ItemJobChanged;
271    private void OnItemJobChanged() {
272      ItemJob_ComputeInParallelChanged(this, EventArgs.Empty);
273      var handler = ItemJobChanged;
274      if (handler != null) handler(this, EventArgs.Empty);
275    }
276
277    public event EventHandler IsFinishedJobDownloadedChanged;
278    private void OnIsFinishedJobDownloadedChanged() {
279      var handler = IsFinishedJobDownloadedChanged;
280      if (handler != null) handler(this, EventArgs.Empty);
281    }
282
283    private void RegisterJobEvents() {
284      if (job != null)
285        job.PropertyChanged += new PropertyChangedEventHandler(job_PropertyChanged);
286    }
287
288    private void DeregisterJobEvents() {
289      if (job != null)
290        job.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(job_PropertyChanged);
291    }
292
293    private void job_PropertyChanged(object sender, PropertyChangedEventArgs e) {
294      if (e.PropertyName == "State") {
295        IsFinishedJobDownloaded = false;
296      }
297    }
298    #endregion
299
300    /// <summary>
301    /// Returns a list of HiveJobs including this and all its child-jobs recursively
302    /// </summary>
303    public IEnumerable<HiveJob> GetAllHiveJobs() {
304      childHiveJobsLock.EnterReadLock();
305      try {
306        var jobs = new List<HiveJob>();
307        jobs.Add(this);
308        foreach (HiveJob child in this.childHiveJobs) {
309          jobs.AddRange(child.GetAllHiveJobs());
310        }
311        return jobs;
312      }
313      finally { childHiveJobsLock.ExitReadLock(); }
314    }
315
316    public HiveJob GetParentByJobId(Guid jobId) {
317      childHiveJobsLock.EnterReadLock();
318      try {
319        if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
320          return this;
321        foreach (HiveJob child in this.childHiveJobs) {
322          HiveJob result = child.GetParentByJobId(jobId);
323          if (result != null)
324            return result;
325        }
326        return null;
327      }
328      finally { childHiveJobsLock.ExitWriteLock(); }
329    }
330
331    /// <summary>
332    /// Searches for an HiveJob object with the correct jobId recursively
333    /// </summary>
334    public HiveJob GetHiveJobByJobId(Guid jobId) {
335      if (this.Job.Id == jobId) {
336        return this;
337      } else {
338        childHiveJobsLock.EnterReadLock();
339        try {
340          foreach (HiveJob child in this.childHiveJobs) {
341            HiveJob result = child.GetHiveJobByJobId(jobId);
342            if (result != null)
343              return result;
344          }
345        }
346        finally { childHiveJobsLock.ExitReadLock(); }
347      }
348      return null;
349    }
350
351    public void RemoveByJobId(Guid jobId) {
352      childHiveJobsLock.EnterWriteLock();
353      try {
354        IEnumerable<HiveJob> jobs = childHiveJobs.Where(j => j.Job.Id == jobId).ToList();
355        foreach (HiveJob j in jobs) {
356          this.childHiveJobs.Remove(j);
357        }
358        foreach (HiveJob child in childHiveJobs) {
359          child.RemoveByJobId(jobId);
360        }
361      }
362      finally { childHiveJobsLock.ExitWriteLock(); }
363    }
364
365    public IEnumerable<IItemTree<HiveJob>> GetChildItems() {
366      return this.ChildHiveJobs;
367    }
368
369    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
370
371    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> CollectionReset;
372    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
373      var handler = CollectionReset;
374      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
375    }
376
377    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsAdded;
378    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
379      var handler = ItemsAdded;
380      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
381    }
382
383    public event CollectionItemsChangedEventHandler<IItemTree<HiveJob>> ItemsRemoved;
384    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
385      var handler = ItemsRemoved;
386      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
387    }
388
389    private static CollectionItemsChangedEventArgs<IItemTree<HiveJob>> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
390      return new CollectionItemsChangedEventArgs<IItemTree<HiveJob>>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
391    }
392    #endregion
393
394    public void Pause() {
395      if (this.Job.IsParentJob) {
396        childHiveJobsLock.EnterReadLock();
397        try {
398          foreach (var child in childHiveJobs) {
399            ServiceLocator.Instance.CallHiveService(s => s.PauseJob(child.job.Id));
400          }
401        }
402        finally { childHiveJobsLock.ExitReadLock(); }
403      } else {
404        ServiceLocator.Instance.CallHiveService(s => s.PauseJob(this.job.Id));
405      }
406    }
407
408    public void Stop() {
409      if (this.Job.IsParentJob) {
410        childHiveJobsLock.EnterReadLock();
411        try {
412          foreach (var child in childHiveJobs) {
413            ServiceLocator.Instance.CallHiveService(s => s.StopJob(child.job.Id));
414          }
415        }
416        finally { childHiveJobsLock.ExitReadLock(); }
417      } else {
418        ServiceLocator.Instance.CallHiveService(s => s.StopJob(this.job.Id));
419      }
420    }
421
422    public void Restart() {
423      ServiceLocator.Instance.CallHiveService(service => {
424        JobData jobData = new JobData();
425        jobData.JobId = this.job.Id;
426        jobData.Data = PersistenceUtil.Serialize(this.itemJob);
427        service.UpdateJobData(this.Job, jobData);
428        service.RestartJob(this.job.Id);
429        Job job = service.GetJob(this.job.Id);
430        this.job.LastJobDataUpdate = job.LastJobDataUpdate;
431      });
432    }
433
434    public ICollection<IItemTreeNodeAction<HiveJob>> Actions {
435      get {
436        return new List<IItemTreeNodeAction<HiveJob>>();
437      }
438    }
439
440    public virtual void IntegrateChild(ItemJob job, Guid childJobId) { }
441
442    /// <summary>
443    /// Delete ItemJob
444    /// </summary>
445    public void ClearData() {
446      this.ItemJob.Item = null;
447    }
448  }
449
450  [Item("Hive Job", "Represents a hive job.")]
451  [StorableClass]
452  public class HiveJob<T> : HiveJob where T : ItemJob {
453
454    public new T ItemJob {
455      get { return (T)base.ItemJob; }
456      internal set { base.ItemJob = value; }
457    }
458
459    #region Constructors and Cloning
460    public HiveJob() : base() { }
461    public HiveJob(T itemJob) : base(itemJob, true) { }
462    protected HiveJob(HiveJob original, Cloner cloner)
463      : base(original, cloner) {
464    }
465    public override IDeepCloneable Clone(Cloner cloner) {
466      return new HiveJob<T>(this, cloner);
467    }
468    #endregion
469  }
470}
Note: See TracBrowser for help on using the repository browser.