Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

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