Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs @ 6357

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

#1233

  • extended statistics recording:
    • execution times of users are captured
    • execution times and start-to-finish time of finished jobs is captured (to computer hive overhead)
    • data of deleted jobs is automatically captured in DeletedJobStatistics
  • changed ExecutionTime type in database from string to float (milliseconds are stored instead of TimeSpan.ToString())
  • added IsPrivileged field to job to indicate if it should be executed in a privileged sandbox
  • added CpuUtilization field to slave to be able to report cpu utilization
  • added GetJobsByResourceId to retrieve all jobs which are currently beeing calculated in a slave(-group)
  • TransactionManager now allows to use serializable tranactions (used for lifecycle trigger)
File size: 16.1 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 HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Hive;
30
31namespace HeuristicLab.Clients.Hive {
32  public class RefreshableHiveExperiment : IHiveItem, IDeepCloneable, IContent, IProgressReporter {
33    private JobResultPoller jobResultPoller;
34    private ConcurrentJobDownloader<ItemJob> jobDownloader;
35    private static object locker = new object();
36
37    private HiveExperiment hiveExperiment;
38    public HiveExperiment HiveExperiment {
39      get { return hiveExperiment; }
40      set {
41        if (value != hiveExperiment) {
42          if (value == null)
43            throw new ArgumentNullException();
44
45          if (hiveExperiment != null) DergisterHiveExperimentEvents();
46          hiveExperiment = value;
47          if (hiveExperiment != null) RegisterHiveExperimentEvents();
48          OnHiveExperimentChanged();
49        }
50      }
51    }
52
53    /** include jobs when refreshing **/
54    private bool includeJobs;
55    public bool IncludeJobs {
56      get { return includeJobs; }
57      set { includeJobs = value; }
58    }
59
60    private bool refreshAutomatically;
61    public bool RefreshAutomatically {
62      get { return refreshAutomatically; }
63      set {
64        lock (locker) {
65          if (refreshAutomatically != value) {
66            refreshAutomatically = value;
67            OnRefreshAutomaticallyChanged();
68          }
69          if (RefreshAutomatically) {
70            if (hiveExperiment.HiveJobs != null && hiveExperiment.HiveJobs.Count > 0 && (jobResultPoller == null || !jobResultPoller.IsPolling)) {
71              StartResultPolling();
72            }
73          } else {
74            StopResultPolling();
75          }
76        }
77      }
78    }
79
80    // if true, all control buttons should be enabled. otherwise disabled (used for HiveEngine)
81    private bool isControllable = true;
82    public bool IsControllable {
83      get { return isControllable; }
84      set {
85        if (value != isControllable) {
86          isControllable = value;
87          OnIsControllableChanged();
88        }
89      }
90    }
91
92    private ILog log;
93    public ILog Log {
94      get { return log; }
95      set { log = value; }
96    }
97    private static object logLocker = new object();
98   
99
100    #region Constructors and Cloning
101    public RefreshableHiveExperiment() {
102      this.includeJobs = true;
103      this.refreshAutomatically = true;
104      this.HiveExperiment = new HiveExperiment();
105      this.log = new Log();
106      this.jobDownloader = new ConcurrentJobDownloader<ItemJob>(2, 2);
107      this.jobDownloader.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobDownloader_ExceptionOccured);
108    }
109    public RefreshableHiveExperiment(HiveExperiment hiveExperiment) {
110      this.includeJobs = true;
111      this.refreshAutomatically = true;
112      this.HiveExperiment = hiveExperiment;
113      this.log = new Log();
114      this.jobDownloader = new ConcurrentJobDownloader<ItemJob>(2, 2);
115      this.jobDownloader.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobDownloader_ExceptionOccured);
116    }
117    protected RefreshableHiveExperiment(RefreshableHiveExperiment original, Cloner cloner) {
118      cloner.RegisterClonedObject(original, this);
119      this.HiveExperiment = original.HiveExperiment;
120      this.IncludeJobs = original.IncludeJobs;
121      this.IsControllable = original.IsControllable;
122      this.Log = cloner.Clone(original.Log);
123      this.RefreshAutomatically = false; // do not start results polling automatically
124      this.jobDownloader = new ConcurrentJobDownloader<ItemJob>(2, 2);
125      this.jobDownloader.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobDownloader_ExceptionOccured);
126    }
127    public IDeepCloneable Clone(Cloner cloner) {
128      return new RefreshableHiveExperiment(this, cloner);
129    }
130    public object Clone() {
131      return this.Clone(new Cloner());
132    }
133    #endregion
134
135    private void hiveExperiment_HiveJobsChanged(object sender, EventArgs e) {
136      if (jobResultPoller != null && jobResultPoller.IsPolling) {
137        jobResultPoller.Stop();
138        DeregisterResultPollingEvents();
139      }
140      if (hiveExperiment.HiveJobs != null && hiveExperiment.HiveJobs.Count > 0 && hiveExperiment.GetAllHiveJobs().All(x => x.Job.Id != Guid.Empty)) {
141        if (this.RefreshAutomatically)
142          StartResultPolling();
143      }
144    }
145
146    #region JobResultPoller Events
147
148    public void StartResultPolling() {
149      if (jobResultPoller == null) {
150        jobResultPoller = new JobResultPoller(hiveExperiment.Id, /*ApplicationConstants.ResultPollingInterval*/new TimeSpan(0, 0, 5)); //TODO: find a better place for ApplicationConstants
151        RegisterResultPollingEvents();
152        jobResultPoller.AutoResumeOnException = !IsControllable;
153      }
154
155      if (!jobResultPoller.IsPolling) {
156        jobResultPoller.Start();
157      }
158    }
159
160    public void StopResultPolling() {
161      if (jobResultPoller != null && jobResultPoller.IsPolling) {
162        jobResultPoller.Stop();
163      }
164    }
165
166    private void RegisterResultPollingEvents() {
167      jobResultPoller.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
168      jobResultPoller.JobResultsReceived += new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
169      jobResultPoller.IsPollingChanged += new EventHandler(jobResultPoller_IsPollingChanged);
170    }
171    private void DeregisterResultPollingEvents() {
172      jobResultPoller.ExceptionOccured -= new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
173      jobResultPoller.JobResultsReceived -= new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
174      jobResultPoller.IsPollingChanged -= new EventHandler(jobResultPoller_IsPollingChanged);
175    }
176    private void jobResultPoller_IsPollingChanged(object sender, EventArgs e) {
177      if (this.refreshAutomatically != jobResultPoller.IsPolling) {
178        this.refreshAutomatically = jobResultPoller.IsPolling;
179        OnRefreshAutomaticallyChanged();
180      }
181    }
182    private void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
183      foreach (LightweightJob lightweightJob in e.Value) {
184        HiveJob hiveJob = GetHiveJobById(lightweightJob.Id);
185        if (hiveJob != null) {
186          // lastJobDataUpdate equals DateTime.MinValue right after it was uploaded. When the first results are polled, this value is updated
187          if (hiveJob.Job.State == JobState.Offline && lightweightJob.State != JobState.Finished && lightweightJob.State != JobState.Failed && lightweightJob.State != JobState.Aborted) {
188            hiveJob.Job.LastJobDataUpdate = lightweightJob.LastJobDataUpdate;
189          }
190
191          hiveJob.UpdateFromLightweightJob(lightweightJob);
192
193          if (!hiveJob.IsFinishedJobDownloaded && !hiveJob.IsDownloading && hiveJob.Job.LastJobDataUpdate < lightweightJob.LastJobDataUpdate) {
194            LogMessage(string.Format("Downloading job {0}", lightweightJob.Id));
195            hiveJob.IsDownloading = true;
196            jobDownloader.DownloadJob(hiveJob.Job, (localJob, itemJob) => {
197              LogMessage(string.Format("Finished downloading job {0}", localJob.Id));
198              HiveJob localHiveJob = GetHiveJobById(localJob.Id);
199
200              if (itemJob == null) {
201                localHiveJob.IsDownloading = false;
202              }
203
204              if (itemJob == null) {
205                // something bad happened to this job. bad job, BAAAD job!
206              } else {
207                // if the job is paused, download but don't integrate into parent optimizer (to avoid Prepare)
208
209                if (localJob.State == JobState.Paused) {
210                  localHiveJob.ItemJob = itemJob;
211                } else {
212                  if (localJob.ParentJobId.HasValue) {
213                    HiveJob parentHiveJob = GetHiveJobById(localJob.ParentJobId.Value);
214                    parentHiveJob.IntegrateChild(itemJob, localJob.Id);
215                  } else {
216                    localHiveJob.ItemJob = itemJob;
217                  }
218                }
219                localHiveJob.IsDownloading = false;
220                localHiveJob.Job.LastJobDataUpdate = localJob.LastJobDataUpdate;
221              }
222            });
223          }
224        }
225      }
226      GC.Collect(); // force GC, because .NET is too lazy here (deserialization takes a lot of memory)
227      if (AllJobsFinished()) {
228        hiveExperiment.ExecutionState = Core.ExecutionState.Stopped;
229        StopResultPolling();
230      }
231      UpdateTotalExecutionTime();
232      UpdateStatistics();
233    }
234
235    // synchronized logging
236    private void LogException(Exception exception) {
237      lock (logLocker) {
238        this.log.LogException(exception);
239      }
240    }
241    // synchronized logging
242    private void LogMessage(string message) {
243      lock (logLocker) {
244        this.log.LogMessage(message);
245      }
246    }
247
248    public HiveJob GetHiveJobById(Guid jobId) {
249      foreach (HiveJob job in hiveExperiment.HiveJobs) {
250        var hj = job.GetHiveJobByJobId(jobId);
251        if (hj != null)
252          return hj;
253      }
254      return null;
255    }
256    private void UpdateStatistics() {
257      var jobs = hiveExperiment.GetAllHiveJobs();
258      hiveExperiment.JobCount = jobs.Count();
259      hiveExperiment.CalculatingCount = jobs.Count(j => j.Job.State == JobState.Calculating);
260      hiveExperiment.FinishedCount = jobs.Count(j => j.Job.State == JobState.Finished);
261      OnJobStatisticsChanged();
262    }
263
264    public bool AllJobsFinished() {
265      return hiveExperiment.GetAllHiveJobs().All(j => (j.Job.State == JobState.Finished
266                                                   || j.Job.State == JobState.Aborted
267                                                   || j.Job.State == JobState.Failed)
268                                                   && j.IsFinishedJobDownloaded);
269    }
270
271    private void jobResultPoller_ExceptionOccured(object sender, EventArgs<Exception> e) {
272      OnExceptionOccured(e.Value);
273    }
274    private void jobDownloader_ExceptionOccured(object sender, EventArgs<Exception> e) {
275      OnExceptionOccured(e.Value);
276    }
277    public void UpdateTotalExecutionTime() {
278      hiveExperiment.ExecutionTime = TimeSpan.FromMilliseconds(hiveExperiment.GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.TotalMilliseconds));
279    }
280    #endregion
281
282    private void RegisterHiveExperimentEvents() {
283      hiveExperiment.HiveJobsChanged += new EventHandler(hiveExperiment_HiveJobsChanged);
284      hiveExperiment.ToStringChanged += new EventHandler(hiveExperiment_ToStringChanged);
285      hiveExperiment.PropertyChanged += new PropertyChangedEventHandler(hiveExperiment_PropertyChanged);
286      hiveExperiment.ItemImageChanged += new EventHandler(hiveExperiment_ItemImageChanged);
287      hiveExperiment.ModifiedChanged += new EventHandler(hiveExperiment_ModifiedChanged);
288      hiveExperiment.IsProgressingChanged += new EventHandler(hiveExperiment_IsProgressingChanged);
289      hiveExperiment.Loaded += new EventHandler(hiveExperiment_Loaded);
290    }
291
292    private void DergisterHiveExperimentEvents() {
293      hiveExperiment.HiveJobsChanged -= new EventHandler(hiveExperiment_HiveJobsChanged);
294      hiveExperiment.ToStringChanged -= new EventHandler(hiveExperiment_ToStringChanged);
295      hiveExperiment.PropertyChanged -= new PropertyChangedEventHandler(hiveExperiment_PropertyChanged);
296      hiveExperiment.ItemImageChanged -= new EventHandler(hiveExperiment_ItemImageChanged);
297      hiveExperiment.ModifiedChanged -= new EventHandler(hiveExperiment_ModifiedChanged);
298      hiveExperiment.IsProgressingChanged -= new EventHandler(hiveExperiment_IsProgressingChanged);
299      hiveExperiment.Loaded -= new EventHandler(hiveExperiment_Loaded);
300    }
301
302    private void hiveExperiment_Loaded(object sender, EventArgs e) {
303      this.UpdateTotalExecutionTime();
304
305      if (hiveExperiment.ExecutionState != ExecutionState.Stopped) {
306        this.RefreshAutomatically = true;
307      }
308    }
309
310    #region Events
311    public event EventHandler RefreshAutomaticallyChanged;
312    private void OnRefreshAutomaticallyChanged() {
313      var handler = RefreshAutomaticallyChanged;
314      if (handler != null) handler(this, EventArgs.Empty);
315    }
316
317    public event EventHandler HiveExperimentChanged;
318    private void OnHiveExperimentChanged() {
319      var handler = HiveExperimentChanged;
320      if (handler != null) handler(this, EventArgs.Empty);
321    }
322
323    public event EventHandler ModifiedChanged;
324    private void hiveExperiment_ModifiedChanged(object sender, EventArgs e) {
325      var handler = ModifiedChanged;
326      if (handler != null) handler(sender, e);
327    }
328
329    public event EventHandler ItemImageChanged;
330    private void hiveExperiment_ItemImageChanged(object sender, EventArgs e) {
331      var handler = ItemImageChanged;
332      if (handler != null) handler(this, e);
333    }
334
335    public event PropertyChangedEventHandler PropertyChanged;
336    private void hiveExperiment_PropertyChanged(object sender, PropertyChangedEventArgs e) {
337      var handler = PropertyChanged;
338      if (handler != null) handler(sender, e);
339    }
340
341    public event EventHandler ToStringChanged;
342    private void hiveExperiment_ToStringChanged(object sender, EventArgs e) {
343      var handler = ToStringChanged;
344      if (handler != null) handler(this, e);
345    }
346
347    public event EventHandler IsProgressingChanged;
348    private void hiveExperiment_IsProgressingChanged(object sender, EventArgs e) {
349      var handler = IsProgressingChanged;
350      if (handler != null) handler(sender, e);
351    }
352
353    public event EventHandler IsControllableChanged;
354    private void OnIsControllableChanged() {
355      var handler = IsControllableChanged;
356      if (handler != null) handler(this, EventArgs.Empty);
357    }
358
359    public event EventHandler JobStatisticsChanged;
360    private void OnJobStatisticsChanged() {
361      var handler = JobStatisticsChanged;
362      if (handler != null) handler(this, EventArgs.Empty);
363    }
364
365    public event EventHandler<EventArgs<Exception>> ExceptionOccured;
366    private void OnExceptionOccured(Exception exception) {
367      LogException(exception);
368      var handler = ExceptionOccured;
369      if (handler != null) handler(this, new EventArgs<Exception>(exception));
370    }
371    #endregion
372
373    public Guid Id {
374      get { return hiveExperiment.Id; }
375      set { hiveExperiment.Id = value; }
376    }
377    public bool Modified {
378      get { return hiveExperiment.Modified; }
379    }
380    public void Store() {
381      hiveExperiment.Store();
382    }
383    public string ItemDescription {
384      get { return hiveExperiment.ItemDescription; }
385    }
386    public Image ItemImage {
387      get { return hiveExperiment.ItemImage; }
388    }
389    public string ItemName {
390      get { return hiveExperiment.ItemName; }
391    }
392    public Version ItemVersion {
393      get { return hiveExperiment.ItemVersion; }
394    }
395
396
397    #region IProgressReporter Members
398    public IProgress Progress {
399      get { return HiveExperiment.Progress; }
400    }
401
402    public bool IsProgressing {
403      get { return HiveExperiment.IsProgressing; }
404    }
405    #endregion
406
407    public override string ToString() {
408      return HiveExperiment.ToString();
409    }
410  }
411}
Note: See TracBrowser for help on using the repository browser.