Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs @ 5955

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

#1233

  • seperated ExperimentMangerClient (OKB-Style, contains business logic) and HiveExperiment (mainly only contains information)
  • fixed redundant cloning methods in dtos
  • added simple statistics in HiveExperiment which the user can see before downloading an experiment
  • added db-delete cascade for slaves and statelogs - now slaves can be safely deleted
File size: 11.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.ComponentModel;
25using System.Linq;
26using HeuristicLab.Clients.Hive.Jobs;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Optimization;
30
31namespace HeuristicLab.Clients.Hive {
32
33  public partial class HiveExperiment : IDeepCloneable, IContent, IProgressReporter {
34    private JobResultPoller jobResultPoller;
35
36    private bool useLocalPlugins;
37    public bool UseLocalPlugins {
38      get { return useLocalPlugins; }
39      set { useLocalPlugins = value; }
40    }
41
42    private ExecutionState executionState;
43    public ExecutionState ExecutionState {
44      get { return executionState; }
45      internal set {
46        if (executionState != value) {
47          executionState = value;
48          OnExecutionStateChanged();
49        }
50      }
51    }
52
53    private TimeSpan executionTime;
54    public TimeSpan ExecutionTime {
55      get { return executionTime; }
56      internal set {
57        if (executionTime != value) {
58          executionTime = value;
59          OnExecutionTimeChanged();
60        }
61      }
62    }
63
64    private HiveJob hiveJob;
65    public HiveJob HiveJob {
66      get { return hiveJob; }
67      set {
68        DeregisterHiveJobEvents();
69        if (hiveJob != value) {
70          hiveJob = value;
71          RegisterHiveJobEvents();
72          OnHiveJobChanged();
73        }
74      }
75    }
76
77    private bool isProgressing;
78    public bool IsProgressing {
79      get { return isProgressing; }
80      set {
81        if (isProgressing != value) {
82          isProgressing = value;
83          OnIsProgressingChanged();
84        }
85      }
86    }
87
88    /** include jobs when refreshing **/
89    private bool includeJobs;
90    public bool IncludeJobs {
91      get { return includeJobs; }
92      set { includeJobs = value; }
93    }
94
95    private bool refreshAutomatically;
96    public bool RefreshAutomatically {
97      get { return refreshAutomatically; }
98      set {
99        if (refreshAutomatically != value) {
100          refreshAutomatically = value;
101          OnRefreshAutomaticallyChanged();
102          if (RefreshAutomatically) {
103            StartResultPolling();
104          } else {
105            StopResultPolling();
106          }
107        }
108      }
109    }
110
111    private IProgress progress;
112    public IProgress Progress {
113      get { return progress; }
114      set { this.progress = value; }
115    }
116
117    #region Constructors and Cloning
118    public HiveExperiment() {
119      this.ResourceNames = "HEAL";
120      this.includeJobs = true;
121      this.refreshAutomatically = true;
122    }
123
124    protected HiveExperiment(HiveExperiment original, Cloner cloner) {
125      cloner.RegisterClonedObject(original, this);
126      this.RootJobId = original.RootJobId;
127      this.OwnerUserId = original.OwnerUserId;
128      this.DateCreated = original.DateCreated;
129      this.ResourceNames = original.ResourceNames;
130      this.LastAccessed = original.LastAccessed;
131      this.Name = original.Name;
132      this.Description = original.Description;
133      this.Id = original.Id;
134
135      this.UseLocalPlugins = original.UseLocalPlugins;
136      this.ExecutionTime = original.ExecutionTime;
137    }
138    public override IDeepCloneable Clone(Cloner cloner) {
139      return new HiveExperiment(this, cloner);
140    }
141    #endregion
142
143    public override string ToString() {
144      return Name;
145    }
146
147    #region Events
148    public event EventHandler ExecutionTimeChanged;
149    private void OnExecutionTimeChanged() {
150      EventHandler handler = ExecutionTimeChanged;
151      if (handler != null) handler(this, EventArgs.Empty);
152    }
153
154    public event EventHandler ExecutionStateChanged;
155    private void OnExecutionStateChanged() {
156      EventHandler handler = ExecutionStateChanged;
157      if (handler != null) handler(this, EventArgs.Empty);
158    }
159
160    public event EventHandler HiveJobChanged;
161    private void OnHiveJobChanged() {
162      if (jobResultPoller != null && jobResultPoller.IsPolling) {
163        jobResultPoller.Stop();
164        DeregisterResultPollingEvents();
165      }
166      if (HiveJob != null && HiveJob.Job.Id != Guid.Empty) {
167        if (this.RefreshAutomatically)
168          StartResultPolling();
169      }
170      EventHandler handler = HiveJobChanged;
171      if (handler != null) handler(this, EventArgs.Empty);
172    }
173
174    public event EventHandler IsProgressingChanged;
175    private void OnIsProgressingChanged() {
176      EventHandler handler = IsProgressingChanged;
177      if (handler != null) handler(this, EventArgs.Empty);
178    }
179
180    public event EventHandler RefreshAutomaticallyChanged;
181    private void OnRefreshAutomaticallyChanged() {
182      EventHandler handler = RefreshAutomaticallyChanged;
183      if (handler != null) handler(this, EventArgs.Empty);
184    }
185    #endregion
186
187    private void RegisterHiveJobEvents() {
188      if (HiveJob != null) {
189        HiveJob.JobStateChanged += new EventHandler(HiveJob_JobStateChanged);
190      }
191    }
192
193    private void DeregisterHiveJobEvents() {
194      if (HiveJob != null) {
195        HiveJob.JobStateChanged -= new EventHandler(HiveJob_JobStateChanged);
196      }
197    }
198
199    private void HiveJob_JobStateChanged(object sender, EventArgs e) {
200      if (this.HiveJob != null) {
201        this.RootJobId = HiveJob.Job.Id;
202      }
203    }
204
205    public Experiment GetExperiment() {
206      if (this.HiveJob != null) {
207        return HiveJob.OptimizerJob.OptimizerAsExperiment;
208      }
209      return null;
210    }
211
212    public void SetExperiment(Experiment experiment) {
213      this.HiveJob = new HiveJob(experiment);
214    }
215
216    protected override void OnPropertyChanged(PropertyChangedEventArgs e) {
217      base.OnPropertyChanged(e);
218      if (e.PropertyName == "Name") {
219        OnToStringChanged();
220      }
221    }
222
223    #region JobResultPoller Events
224
225    public void StartResultPolling() {
226      if (jobResultPoller == null) {
227        jobResultPoller = new JobResultPoller(HiveJob, /*ApplicationConstants.ResultPollingInterval*/new TimeSpan(0, 0, 5)); //TODO: find a better place for ApplicationConstants
228        RegisterResultPollingEvents();
229      }
230
231      if (!jobResultPoller.IsPolling) {
232        jobResultPoller.Start();
233      }
234    }
235
236    public void StopResultPolling() {
237      if (jobResultPoller.IsPolling) {
238        jobResultPoller.Stop();
239      }
240    }
241
242    private void RegisterResultPollingEvents() {
243      jobResultPoller.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
244      jobResultPoller.JobResultsReceived += new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
245      jobResultPoller.IsPollingChanged += new EventHandler(jobResultPoller_IsPollingChanged);
246    }
247    private void DeregisterResultPollingEvents() {
248      jobResultPoller.ExceptionOccured -= new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
249      jobResultPoller.JobResultsReceived -= new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
250      jobResultPoller.IsPollingChanged -= new EventHandler(jobResultPoller_IsPollingChanged);
251    }
252    private void jobResultPoller_IsPollingChanged(object sender, EventArgs e) {
253      this.refreshAutomatically = jobResultPoller.IsPolling;
254      OnRefreshAutomaticallyChanged();
255    }
256    private void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
257      foreach (LightweightJob lightweightJob in e.Value) {
258        HiveJob hj = hiveJob.GetHiveJobByJobId(lightweightJob.Id);
259        if (hj != null) {
260          DateTime lastJobDataUpdate = hj.Job.LastJobDataUpdate;
261          hj.UpdateFromLightweightJob(lightweightJob);
262
263          // lastJobDataUpdate equals DateTime.MinValue right after it was uploaded. When the first results are polled, this value is updated
264          if (lastJobDataUpdate != DateTime.MinValue && lastJobDataUpdate < hj.Job.LastJobDataUpdate) {
265            OptimizerJob optimizerJob = ExperimentManagerClient.LoadOptimizerJob(hj.Job.Id);
266            if (optimizerJob == null) {
267              // something bad happened to this job. bad job, BAAAD job!
268            } else {
269              // if the job is paused, download but don't integrate into parent optimizer (to avoid Prepare)
270              if (hj.Job.State == JobState.Paused) {
271                hj.OptimizerJob = optimizerJob;
272              } else {
273                if (lightweightJob.ParentJobId.HasValue) {
274                  HiveJob parentHiveJob = HiveJob.GetHiveJobByJobId(lightweightJob.ParentJobId.Value);
275                  parentHiveJob.UpdateChildOptimizer(optimizerJob, hj.Job.Id);
276                }
277              }
278            }
279          }
280        }
281      }
282      GC.Collect(); // force GC, because .NET is too lazy here (deserialization takes a lot of memory)
283      if (AllJobsFinished()) {
284        this.ExecutionState = Core.ExecutionState.Stopped;
285        StopResultPolling();
286        //OnStopped();
287      }
288      UpdateTotalExecutionTime();
289      UpdateStats();
290    }
291
292    private void UpdateStats() {
293      var jobs = HiveJob.GetAllHiveJobs();
294      this.JobCount = jobs.Count();
295      this.CalculatingCount = jobs.Count(j => j.Job.State == JobState.Calculating);
296      this.FinishedCount = jobs.Count(j => j.Job.State == JobState.Finished);
297    }
298
299    private bool AllJobsFinished() {
300      return HiveJob.GetAllHiveJobs().All(j => j.Job.State == JobState.Finished
301                                            || j.Job.State == JobState.Aborted
302                                            || j.Job.State == JobState.Failed);
303    }
304
305    private void jobResultPoller_ExceptionOccured(object sender, EventArgs<Exception> e) {
306      //OnExceptionOccured(e.Value);
307    }
308
309    public void UpdateTotalExecutionTime() {
310      this.ExecutionTime = TimeSpan.FromMilliseconds(HiveJob.GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.HasValue ? x.Job.ExecutionTime.Value.TotalMilliseconds : 0));
311    }
312    #endregion
313
314    protected override void RaisePropertyChanged(string propertyName) {
315      if (!(propertyName == "ExecutionTime")
316        && !(propertyName == "JobCount")
317        && !(propertyName == "CalculatingCount")
318        && !(propertyName == "FinishedCount")) {
319        base.RaisePropertyChanged(propertyName);
320      }
321    }
322  }
323}
Note: See TracBrowser for help on using the repository browser.