Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

  • added semaphores to ensure an appdomain is never unloaded when the start method has not finished
  • HiveEngine uploading and downloading of jobs works and is displayed in the view
File size: 13.8 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    #region Constructors and Cloning
98    public RefreshableHiveExperiment() {
99      this.includeJobs = true;
100      this.refreshAutomatically = true;
101      this.HiveExperiment = new HiveExperiment();
102    }
103    public RefreshableHiveExperiment(HiveExperiment hiveExperiment) {
104      this.includeJobs = true;
105      this.refreshAutomatically = true;
106      this.HiveExperiment = hiveExperiment;
107    }
108    protected RefreshableHiveExperiment(RefreshableHiveExperiment original, Cloner cloner) {
109      cloner.RegisterClonedObject(original, this);
110      this.HiveExperiment = original.HiveExperiment;
111      this.RefreshAutomatically = original.RefreshAutomatically;
112      this.IncludeJobs = original.IncludeJobs;
113      this.IsControllable = original.IsControllable;
114    }
115    public IDeepCloneable Clone(Cloner cloner) {
116      return new RefreshableHiveExperiment(this, cloner);
117    }
118    public object Clone() {
119      return this.Clone(new Cloner());
120    }
121    #endregion
122
123    private void hiveExperiment_HiveJobsChanged(object sender, EventArgs e) {
124      if (jobResultPoller != null && jobResultPoller.IsPolling) {
125        jobResultPoller.Stop();
126        DeregisterResultPollingEvents();
127      }
128      if (hiveExperiment.HiveJobs != null && hiveExperiment.HiveJobs.Count > 0 && hiveExperiment.GetAllHiveJobs().All(x => x.Job.Id != Guid.Empty)) {
129        if (this.RefreshAutomatically)
130          StartResultPolling();
131      }
132    }
133
134    #region JobResultPoller Events
135
136    public void StartResultPolling() {
137      if (jobResultPoller == null) {
138        jobResultPoller = new JobResultPoller(hiveExperiment.Id, /*ApplicationConstants.ResultPollingInterval*/new TimeSpan(0, 0, 5)); //TODO: find a better place for ApplicationConstants
139        RegisterResultPollingEvents();
140      }
141
142      if (!jobResultPoller.IsPolling) {
143        jobResultPoller.Start();
144      }
145    }
146
147    public void StopResultPolling() {
148      if (jobResultPoller != null && jobResultPoller.IsPolling) {
149        jobResultPoller.Stop();
150      }
151    }
152
153    private void RegisterResultPollingEvents() {
154      jobResultPoller.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
155      jobResultPoller.JobResultsReceived += new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
156      jobResultPoller.IsPollingChanged += new EventHandler(jobResultPoller_IsPollingChanged);
157    }
158    private void DeregisterResultPollingEvents() {
159      jobResultPoller.ExceptionOccured -= new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
160      jobResultPoller.JobResultsReceived -= new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
161      jobResultPoller.IsPollingChanged -= new EventHandler(jobResultPoller_IsPollingChanged);
162    }
163    private void jobResultPoller_IsPollingChanged(object sender, EventArgs e) {
164      this.refreshAutomatically = jobResultPoller.IsPolling;
165      OnRefreshAutomaticallyChanged();
166    }
167    private void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
168      foreach (LightweightJob lightweightJob in e.Value) {
169        HiveJob hj = GetHiveJobById(lightweightJob.Id);
170        if (hj != null) {
171          DateTime lastJobDataUpdate = hj.Job.LastJobDataUpdate;
172          hj.UpdateFromLightweightJob(lightweightJob);
173
174          // lastJobDataUpdate equals DateTime.MinValue right after it was uploaded. When the first results are polled, this value is updated
175          if (lastJobDataUpdate != DateTime.MinValue && lastJobDataUpdate < hj.Job.LastJobDataUpdate) {
176            jobDownloader.DownloadJob(hj.Job.Id, (id, itemJob, exception) => {
177              if (exception != null) {
178                throw new ConcurrentJobDownloaderException("Downloading job failed.", exception);
179              }
180
181              if (itemJob == null) {
182                // something bad happened to this job. bad job, BAAAD job!
183              } else {
184                // if the job is paused, download but don't integrate into parent optimizer (to avoid Prepare)
185                if (hj.Job.State == JobState.Paused) {
186                  hj.ItemJob = itemJob;
187                } else {
188                  if (lightweightJob.ParentJobId.HasValue) {
189                    HiveJob parentHiveJob = GetHiveJobById(lightweightJob.ParentJobId.Value);
190                    parentHiveJob.IntegrateChild(itemJob, hj.Job.Id);
191                  } else {
192                    hj.ItemJob = itemJob;
193                  }
194                }
195              }
196            });
197          }
198        }
199      }
200      GC.Collect(); // force GC, because .NET is too lazy here (deserialization takes a lot of memory)
201      if (AllJobsFinished()) {
202        hiveExperiment.ExecutionState = Core.ExecutionState.Stopped;
203        StopResultPolling();
204      }
205      UpdateTotalExecutionTime();
206      UpdateStats();
207    }
208
209    public HiveJob GetHiveJobById(Guid jobId) {
210      foreach (HiveJob job in hiveExperiment.HiveJobs) {
211        var hj = job.GetHiveJobByJobId(jobId);
212        if (hj != null)
213          return hj;
214      }
215      return null;
216    }
217
218    private void UpdateStats() {
219      var jobs = hiveExperiment.GetAllHiveJobs();
220      hiveExperiment.JobCount = jobs.Count();
221      hiveExperiment.CalculatingCount = jobs.Count(j => j.Job.State == JobState.Calculating);
222      hiveExperiment.FinishedCount = jobs.Count(j => j.Job.State == JobState.Finished);
223    }
224
225    public bool AllJobsFinished() {
226      return hiveExperiment.GetAllHiveJobs().All(j => (j.Job.State == JobState.Finished
227                                                   || j.Job.State == JobState.Aborted
228                                                   || j.Job.State == JobState.Failed)
229                                                   && j.ItemJobDownloaded);
230    }
231
232    //public bool AllJobsFinishedAndDownloaded() {
233    //  return this.AllJobsFinished() && hiveExperiment.GetAllHiveJobs().All(j => j.JobItem.;
234    //}
235
236    private void jobResultPoller_ExceptionOccured(object sender, EventArgs<Exception> e) {
237      //OnExceptionOccured(e.Value);
238    }
239
240    public void UpdateTotalExecutionTime() {
241      hiveExperiment.ExecutionTime = TimeSpan.FromMilliseconds(hiveExperiment.GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.HasValue ? x.Job.ExecutionTime.Value.TotalMilliseconds : 0));
242    }
243    #endregion
244
245    private void RegisterHiveExperimentEvents() {
246      hiveExperiment.HiveJobsChanged += new EventHandler(hiveExperiment_HiveJobsChanged);
247      hiveExperiment.ToStringChanged += new EventHandler(hiveExperiment_ToStringChanged);
248      hiveExperiment.PropertyChanged += new PropertyChangedEventHandler(hiveExperiment_PropertyChanged);
249      hiveExperiment.ItemImageChanged += new EventHandler(hiveExperiment_ItemImageChanged);
250      hiveExperiment.ModifiedChanged += new EventHandler(hiveExperiment_ModifiedChanged);
251      hiveExperiment.IsProgressingChanged += new EventHandler(hiveExperiment_IsProgressingChanged);
252      hiveExperiment.Loaded += new EventHandler(hiveExperiment_Loaded);
253    }
254
255    private void DergisterHiveExperimentEvents() {
256      hiveExperiment.HiveJobsChanged -= new EventHandler(hiveExperiment_HiveJobsChanged);
257      hiveExperiment.ToStringChanged -= new EventHandler(hiveExperiment_ToStringChanged);
258      hiveExperiment.PropertyChanged -= new PropertyChangedEventHandler(hiveExperiment_PropertyChanged);
259      hiveExperiment.ItemImageChanged -= new EventHandler(hiveExperiment_ItemImageChanged);
260      hiveExperiment.ModifiedChanged -= new EventHandler(hiveExperiment_ModifiedChanged);
261      hiveExperiment.IsProgressingChanged -= new EventHandler(hiveExperiment_IsProgressingChanged);
262      hiveExperiment.Loaded -= new EventHandler(hiveExperiment_Loaded);
263    }
264
265    private void hiveExperiment_Loaded(object sender, EventArgs e) {
266      this.UpdateTotalExecutionTime();
267
268      if (hiveExperiment.ExecutionState != ExecutionState.Stopped) {
269        this.RefreshAutomatically = true;
270      }
271    }
272
273    #region Events
274    public event EventHandler RefreshAutomaticallyChanged;
275    private void OnRefreshAutomaticallyChanged() {
276      var handler = RefreshAutomaticallyChanged;
277      if (handler != null) handler(this, EventArgs.Empty);
278    }
279
280    public event EventHandler HiveExperimentChanged;
281    private void OnHiveExperimentChanged() {
282      var handler = HiveExperimentChanged;
283      if (handler != null) handler(this, EventArgs.Empty);
284    }
285
286    public event EventHandler ModifiedChanged;
287    private void hiveExperiment_ModifiedChanged(object sender, EventArgs e) {
288      var handler = ModifiedChanged;
289      if (handler != null) handler(sender, e);
290    }
291
292    public event EventHandler ItemImageChanged;
293    private void hiveExperiment_ItemImageChanged(object sender, EventArgs e) {
294      var handler = ItemImageChanged;
295      if (handler != null) handler(this, e);
296    }
297
298    public event PropertyChangedEventHandler PropertyChanged;
299    private void hiveExperiment_PropertyChanged(object sender, PropertyChangedEventArgs e) {
300      var handler = PropertyChanged;
301      if (handler != null) handler(sender, e);
302    }
303
304    public event EventHandler ToStringChanged;
305    private void hiveExperiment_ToStringChanged(object sender, EventArgs e) {
306      var handler = ToStringChanged;
307      if (handler != null) handler(this, e);
308    }
309
310    public event EventHandler IsProgressingChanged;
311    private void hiveExperiment_IsProgressingChanged(object sender, EventArgs e) {
312      var handler = IsProgressingChanged;
313      if (handler != null) handler(sender, e);
314    }
315
316    public event EventHandler IsControllableChanged;
317    private void OnIsControllableChanged() {
318      var handler = IsControllableChanged;
319      if (handler != null) handler(this, EventArgs.Empty);
320    }
321    #endregion
322
323    public Guid Id {
324      get { return hiveExperiment.Id; }
325      set { hiveExperiment.Id = value; }
326    }
327    public bool Modified {
328      get { return hiveExperiment.Modified; }
329    }
330    public void Store() {
331      hiveExperiment.Store();
332    }
333    public string ItemDescription {
334      get { return hiveExperiment.ItemDescription; }
335    }
336    public Image ItemImage {
337      get { return hiveExperiment.ItemImage; }
338    }
339    public string ItemName {
340      get { return hiveExperiment.ItemName; }
341    }
342    public Version ItemVersion {
343      get { return hiveExperiment.ItemVersion; }
344    }
345
346
347    #region IProgressReporter Members
348    public IProgress Progress {
349      get { return HiveExperiment.Progress; }
350    }
351
352    public bool IsProgressing {
353      get { return HiveExperiment.IsProgressing; }
354    }
355    #endregion
356
357    public override string ToString() {
358      return HiveExperiment.ToString();
359    }
360  }
361}
Note: See TracBrowser for help on using the repository browser.