Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveExperimentClient.cs @ 5402

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

#1233

  • single sign on with HL
  • local plugins are uploaded if not available online (user can force the useage of local plugins)
  • changed plugin and plugindata db-schema
  • plugin dao tests
File size: 25.3 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.Linq;
25using System.Threading;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Tracing;
29using HeuristicLab.Services.Hive.Common;
30using HeuristicLab.Services.Hive.Common.ServiceContracts;
31using HeuristicLab.Services.Hive.Common.DataTransfer;
32using HeuristicLab.Clients.Hive.Jobs;
33using HeuristicLab.Clients.Common;
34using HeuristicLab.Optimization;
35
36namespace HeuristicLab.Clients.Hive {
37  using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
38  using HeuristicLab.PluginInfrastructure;
39  using System.IO;
40
41  /// <summary>
42  /// An experiment which contains multiple batch runs of algorithms.
43  /// </summary>
44  [Item(itemName, itemDescription)]
45  public class HiveExperimentClient : NamedItem, IExecutable, IProgressReporter {
46    private object locker = new object();
47    private const string itemName = "Hive Experiment";
48    private const string itemDescription = "A runner for a single experiment, which's algorithms are executed in the Hive.";
49    private System.Timers.Timer timer;
50    private DateTime lastUpdateTime;
51    private Guid rootJobId;
52    private JobResultPoller jobResultPoller;
53
54    private Guid hiveExperimentId;
55    public Guid HiveExperimentId {
56      get { return hiveExperimentId; }
57      set { hiveExperimentId = value; }
58    }
59
60    private HiveJob hiveJob;
61    public HiveJob HiveJob {
62      get { return hiveJob; }
63      set {
64        DeregisterHiveJobEvents();
65        if (hiveJob != value) {
66          hiveJob = value;
67          RegisterHiveJobEvents();
68          OnHiveJobChanged();
69        }
70      }
71    }
72
73    private ILog log;
74    public ILog Log {
75      get { return log; }
76    }
77
78    private string resourceIds;
79    public string ResourceIds {
80      get { return resourceIds; }
81      set {
82        if (resourceIds != value) {
83          resourceIds = value;
84          OnResourceIdsChanged();
85        }
86      }
87    }
88
89    private bool isPollingResults;
90    public bool IsPollingResults {
91      get { return isPollingResults; }
92      private set {
93        if (isPollingResults != value) {
94          isPollingResults = value;
95          OnIsPollingResultsChanged();
96        }
97      }
98    }
99
100    private bool isProgressing;
101    public bool IsProgressing {
102      get { return isProgressing; }
103      set {
104        if (isProgressing != value) {
105          isProgressing = value;
106          OnIsProgressingChanged();
107        }
108      }
109    }
110
111    private IProgress progress;
112    public IProgress Progress {
113      get { return progress; }
114    }
115
116    private List<Guid> pluginsNeededIds;
117    public List<Guid> PluginsNeededIds {
118      get { return pluginsNeededIds; }
119      set { pluginsNeededIds = value; }
120    }
121
122    private bool useLocalPlugins;
123    public bool UseLocalPlugins {
124      get { return useLocalPlugins; }
125      set { useLocalPlugins = value; }
126    }
127   
128    public HiveExperimentClient() : base(itemName, itemDescription) {
129      // TODO //this.ResourceIds = HeuristicLab.Hive.Experiment.Properties.Settings.Default.ResourceIds;
130      this.ResourceIds = "HEAL";
131      this.log = new Log();
132      InitTimer();
133    }
134    public HiveExperimentClient(DT.HiveExperiment hiveExperimentDto) : this() {
135      UpdateFromDto(hiveExperimentDto);
136    }
137    protected HiveExperimentClient(HiveExperimentClient original, Cloner cloner)
138      : base(original, cloner) {
139      this.ResourceIds = original.resourceIds;
140      this.ExecutionState = original.executionState;
141      this.ExecutionTime = original.executionTime;
142      this.log = cloner.Clone(original.log);
143      this.lastUpdateTime = original.lastUpdateTime;
144      this.rootJobId = original.rootJobId;
145    }
146    public override IDeepCloneable Clone(Cloner cloner) {
147      return new HiveExperimentClient(this, cloner);
148    }
149
150    public void UpdateFromDto(DT.HiveExperiment hiveExperimentDto) {
151      this.HiveExperimentId = hiveExperimentDto.Id;
152      this.Name = hiveExperimentDto.Name;
153      this.Description = hiveExperimentDto.Description;
154      // TODO: this.ResourceIds = hiveExperimentDto.ResourceIds;
155      this.rootJobId = hiveExperimentDto.RootJobId;
156    }
157
158    public DT.HiveExperiment ToHiveExperimentDto() {
159      return new DT.HiveExperiment() {
160        Id = this.HiveExperimentId,
161        Name = this.Name,
162        Description = this.Description,
163        //ResourceIds = this.ResourceIds,
164        RootJobId = this.rootJobId
165      };
166    }
167
168    public void SetExperiment(Experiment experiment) {
169      this.HiveJob = new HiveJob(experiment);
170      Prepare();
171    }
172
173    private void RegisterHiveJobEvents() {
174      if (HiveJob != null) {
175        HiveJob.JobStateChanged += new EventHandler(HiveJob_JobStateChanged);
176      }
177    }
178
179    private void DeregisterHiveJobEvents() {
180      if (HiveJob != null) {
181        HiveJob.JobStateChanged -= new EventHandler(HiveJob_JobStateChanged);
182      }
183    }
184
185    /// <summary>
186    /// Returns the experiment from the root HiveJob
187    /// </summary>
188    public Experiment GetExperiment() {
189      if (this.HiveJob != null) {
190        return HiveJob.OptimizerJob.OptimizerAsExperiment;
191      }
192      return null;
193    }
194
195    #region IExecutable Members
196    private ExecutionState executionState;
197    public ExecutionState ExecutionState {
198      get { return executionState; }
199      private set {
200        if (executionState != value) {
201          executionState = value;
202          OnExecutionStateChanged();
203        }
204      }
205    }
206
207    private TimeSpan executionTime;
208    public TimeSpan ExecutionTime {
209      get { return executionTime; }
210      private set {
211        if (executionTime != value) {
212          executionTime = value;
213          OnExecutionTimeChanged();
214        }
215      }
216    }
217
218    public void Pause() {
219      throw new NotSupportedException();
220    }
221
222    public void Prepare() {
223      // do nothing
224    }
225
226    public void Start() {
227      OnStarted();
228      ExecutionTime = new TimeSpan();
229      lastUpdateTime = DateTime.Now;
230      this.ExecutionState = Core.ExecutionState.Started;
231
232      Thread t = new Thread(RunUploadExperiment);
233      t.Name = "RunUploadExperimentThread";
234      t.Start();
235    }
236
237    private void RunUploadExperiment() {
238      try {
239        this.progress = new Progress("Connecting to server...");
240        IsProgressing = true;
241        using (Disposable<IHiveService> service = ServiceLocator.Instance.GetService()) {
242          IEnumerable<string> groups = ToResourceIdList(this.ResourceIds);
243          this.HiveJob.SetIndexInParentOptimizerList(null);
244
245          int totalJobCount = this.HiveJob.GetAllHiveJobs().Count();
246          int jobCount = 0;
247
248          this.progress.Status = "Uploading plugins...";
249          this.PluginsNeededIds = GetPluginsNeededIds(this.useLocalPlugins);
250
251          this.progress.Status = "Uploading jobs...";
252          UploadJobWithChildren(service.Obj, this.HiveJob, null, groups, ref jobCount, totalJobCount);
253          this.rootJobId = this.HiveJob.Job.Id;
254          LogMessage("Finished sending jobs to hive");
255
256          // insert or update HiveExperiment
257          this.progress.Status = "Uploading HiveExperiment...";
258
259          DT.HiveExperiment he = service.Obj.GetHiveExperiment(service.Obj.AddHiveExperiment(this.ToHiveExperimentDto()));
260          this.UpdateFromDto(he);
261
262          StartResultPolling();
263        }
264      }
265      catch (Exception e) {
266        OnExceptionOccured(e);
267      }
268      finally {
269        IsProgressing = false;
270      }
271    }
272
273    /// <summary>
274    /// Gets the Ids of all plugins needed for executing the job.
275    /// All loaded plugins are assumed to be necessary.
276    /// If a plugin with the same name and version is already online, it is used. Otherwise the local plugin is uploaded.
277    /// If useLocalPlugins is true, all local plugins are uploaded regardless of the existence of the same plugin online.
278    /// </summary>
279    public static List<Guid> GetPluginsNeededIds(bool useLocalPlugins) {
280      IEnumerable<IPluginDescription> localPlugins = ApplicationManager.Manager.Plugins;
281      List<Guid> pluginsNeededIds = new List<Guid>();
282
283      using (var service = ServiceLocator.Instance.GetService()) {
284        IEnumerable<Plugin> onlinePlugins = service.Obj.GetPlugins();
285
286        foreach (IPluginDescription localPlugin in localPlugins) {
287          Plugin found = onlinePlugins.Where(onlinePlugin => onlinePlugin.Name == localPlugin.Name && onlinePlugin.Version == localPlugin.Version).SingleOrDefault();
288          if (!useLocalPlugins && found != null) {
289            // plugin is available online; reuse
290            pluginsNeededIds.Add(found.Id);
291          } else {
292            // upload the plugin
293            Plugin p = new Plugin() { Name = localPlugin.Name, Version = localPlugin.Version, IsLocal = useLocalPlugins };
294            List<PluginData> pluginDatas = new List<PluginData>();
295
296            foreach (IPluginFile pf in localPlugin.Files) {
297              PluginData pluginData = new PluginData();
298
299              pluginData.Data = File.ReadAllBytes(pf.Name);
300              pluginDatas.Add(pluginData);
301            }
302            pluginsNeededIds.Add(service.Obj.AddPlugin(p, pluginDatas));
303          }
304        }
305      }
306      return pluginsNeededIds;
307    }
308
309    /// <summary>
310    /// Uploads the given job and all its child-jobs while setting the proper parentJobId values for the childs
311    ///
312    /// </summary>
313    /// <param name="service"></param>
314    /// <param name="hiveJob"></param>
315    /// <param name="parentHiveJob">shall be null if its the root job</param>
316    /// <param name="groups"></param>
317    private void UploadJobWithChildren(IHiveService service, HiveJob hiveJob, HiveJob parentHiveJob, IEnumerable<string> groups, ref int jobCount, int totalJobCount) {
318      jobCount++;
319      this.progress.Status = string.Format("Serializing job {0} of {1}", jobCount, totalJobCount);
320      JobData jobData;
321      if (hiveJob.OptimizerJob.ComputeInParallel &&
322        (hiveJob.OptimizerJob.Optimizer is Optimization.Experiment || hiveJob.OptimizerJob.Optimizer is Optimization.BatchRun)) {
323        hiveJob.Job.JobState = JobState.WaitingForChildJobs;
324        hiveJob.OptimizerJob.CollectChildJobs = false; // don't collect child-jobs on slaves
325        jobData = hiveJob.GetAsJobData(true);
326      } else {
327        jobData = hiveJob.GetAsJobData(false);
328      }
329
330      hiveJob.Job.PluginsNeededIds = this.PluginsNeededIds;
331
332      this.progress.Status = string.Format("Uploading job {0} of {1} ({2} kb)", jobCount, totalJobCount, jobData.Data.Count() / 1024);
333      this.progress.ProgressValue = (double)jobCount / totalJobCount;
334
335      if (parentHiveJob != null) {
336        //response = service.AddChildJob(parentHiveJob.Job.Id, serializedJob);
337        hiveJob.Job.Id = service.AddChildJob(parentHiveJob.Job.Id, hiveJob.Job, jobData);
338      } else {
339        // response = service.AddJobWithGroupStrings(serializedJob, groups);
340        hiveJob.Job.Id = service.AddJob(hiveJob.Job, jobData, null); // todo: use ResourceIds
341      }
342
343      LogMessage(hiveJob.Job.Id, "Job sent to Hive");
344
345      foreach (HiveJob child in hiveJob.ChildHiveJobs) {
346        UploadJobWithChildren(service, child, hiveJob, groups, ref jobCount, totalJobCount);
347      }
348    }
349
350    /// <summary>
351    /// Converts a string which can contain Ids separated by ';' to a enumerable
352    /// </summary>
353    private IEnumerable<string> ToResourceIdList(string resourceGroups) {
354      if (!string.IsNullOrEmpty(resourceGroups)) {
355        return resourceIds.Split(';');
356      } else {
357        return new List<string>();
358      }
359    }
360
361    public void Stop() {
362      using (Disposable<IHiveService> service = ServiceLocator.Instance.GetService()) {
363        foreach (HiveJob hj in HiveJob.GetAllHiveJobs()) {
364          service.Obj.StopJob(hj.Job.Id);
365        }
366      }
367    }
368
369    #endregion
370
371    public void StartResultPolling() {
372      if (!jobResultPoller.IsPolling) {
373        jobResultPoller.Start();
374      } else {
375        throw new JobResultPollingException("Result polling already running");
376      }
377    }
378
379    public void StopResultPolling() {
380      if (jobResultPoller.IsPolling) {
381        jobResultPoller.Stop();
382      } else {
383        throw new JobResultPollingException("Result polling not running");
384      }
385    }
386
387    #region HiveJob Events
388    void HiveJob_JobStateChanged(object sender, EventArgs e) {
389      if (HiveJob != null) {
390        rootJobId = HiveJob.Job.Id;
391      }
392    }
393    #endregion
394
395    #region Eventhandler
396
397    public event EventHandler ExecutionTimeChanged;
398    private void OnExecutionTimeChanged() {
399      EventHandler handler = ExecutionTimeChanged;
400      if (handler != null) handler(this, EventArgs.Empty);
401    }
402
403    public event EventHandler ExecutionStateChanged;
404    private void OnExecutionStateChanged() {
405      LogMessage("ExecutionState changed to " + executionState.ToString());
406      EventHandler handler = ExecutionStateChanged;
407      if (handler != null) handler(this, EventArgs.Empty);
408    }
409
410    public event EventHandler Started;
411    private void OnStarted() {
412      LogMessage("Started");
413      timer.Start();
414      EventHandler handler = Started;
415      if (handler != null) handler(this, EventArgs.Empty);
416    }
417
418    public event EventHandler Stopped;
419    private void OnStopped() {
420      LogMessage("Stopped");
421      timer.Stop();
422      EventHandler handler = Stopped;
423      if (handler != null) handler(this, EventArgs.Empty);
424    }
425
426    public event EventHandler Paused;
427    private void OnPaused() {
428      LogMessage("Paused");
429      EventHandler handler = Paused;
430      if (handler != null) handler(this, EventArgs.Empty);
431    }
432
433    public event EventHandler Prepared;
434    protected virtual void OnPrepared() {
435      LogMessage("Prepared");
436      EventHandler handler = Prepared;
437      if (handler != null) handler(this, EventArgs.Empty);
438    }
439
440    public event EventHandler ResourceIdsChanged;
441    protected virtual void OnResourceIdsChanged() {
442      EventHandler handler = ResourceIdsChanged;
443      if (handler != null) handler(this, EventArgs.Empty);
444    }
445
446    public event EventHandler IsResultsPollingChanged;
447    private void OnIsPollingResultsChanged() {
448      if (this.IsPollingResults) {
449        LogMessage("Results Polling Started");
450      } else {
451        LogMessage("Results Polling Stopped");
452      }
453      EventHandler handler = IsResultsPollingChanged;
454      if (handler != null) handler(this, EventArgs.Empty);
455    }
456
457    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
458    private void OnExceptionOccured(Exception e) {
459      var handler = ExceptionOccurred;
460      if (handler != null) handler(this, new EventArgs<Exception>(e));
461    }
462
463    public event EventHandler HiveJobChanged;
464    private void OnHiveJobChanged() {
465      if (jobResultPoller != null && jobResultPoller.IsPolling) {
466        jobResultPoller.Stop();
467        DeregisterResultPollingEvents();
468      }
469      if (HiveJob != null) {
470        jobResultPoller = new JobResultPoller(HiveJob, ApplicationConstants.ResultPollingInterval);
471        RegisterResultPollingEvents();
472      }
473      EventHandler handler = HiveJobChanged;
474      if (handler != null) handler(this, EventArgs.Empty);
475    }
476
477    public event EventHandler IsProgressingChanged;
478    private void OnIsProgressingChanged() {
479      var handler = IsProgressingChanged;
480      if (handler != null) handler(this, EventArgs.Empty);
481    }
482    #endregion
483
484    #region JobResultPoller Events
485    private void RegisterResultPollingEvents() {
486      jobResultPoller.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
487      jobResultPoller.JobResultsReceived += new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
488      jobResultPoller.PollingStarted += new EventHandler(jobResultPoller_PollingStarted);
489      jobResultPoller.PollingFinished += new EventHandler(jobResultPoller_PollingFinished);
490      jobResultPoller.IsPollingChanged += new EventHandler(jobResultPoller_IsPollingChanged);
491    }
492    private void DeregisterResultPollingEvents() {
493      jobResultPoller.ExceptionOccured -= new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
494      jobResultPoller.JobResultsReceived -= new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
495      jobResultPoller.PollingStarted -= new EventHandler(jobResultPoller_PollingStarted);
496      jobResultPoller.PollingFinished -= new EventHandler(jobResultPoller_PollingFinished);
497      jobResultPoller.IsPollingChanged -= new EventHandler(jobResultPoller_IsPollingChanged);
498    }
499    void jobResultPoller_IsPollingChanged(object sender, EventArgs e) {
500      this.IsPollingResults = jobResultPoller.IsPolling;
501    }
502    void jobResultPoller_PollingFinished(object sender, EventArgs e) {
503      LogMessage("Polling results finished");
504    }
505    void jobResultPoller_PollingStarted(object sender, EventArgs e) {
506      LogMessage("Polling results started");
507    }
508    void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
509      foreach (LightweightJob lightweightJob in e.Value) {
510        HiveJob hj = hiveJob.GetHiveJobByJobId(lightweightJob.Id);
511        if (hj != null) {
512          hj.UpdateFromLightweightJob(lightweightJob);
513          if ((hj.Job.JobState == JobState.Aborted ||
514               hj.Job.JobState == JobState.Failed ||
515               hj.Job.JobState == JobState.Finished) &&
516              !hj.IsFinishedOptimizerDownloaded) {
517            LogMessage(hj.Job.Id, "Downloading optimizer for job");
518            OptimizerJob optimizerJob = LoadOptimizerJob(hj.Job.Id);
519            if (optimizerJob == null) {
520              // something bad happened to this job. set to finished to allow the rest beeing downloaded
521              hj.IsFinishedOptimizerDownloaded = true;
522            } else {
523              if (lightweightJob.ParentJobId.HasValue) {
524                HiveJob parentHiveJob = HiveJob.GetHiveJobByJobId(lightweightJob.ParentJobId.Value);
525                parentHiveJob.UpdateChildOptimizer(optimizerJob, hj.Job.Id);
526              } else {
527                this.HiveJob.IsFinishedOptimizerDownloaded = true;
528              }
529            }
530          }
531        }
532      }
533      GC.Collect(); // force GC, because .NET is too lazy here (deserialization takes a lot of memory)
534      if (AllJobsFinished()) {
535        this.ExecutionState = Core.ExecutionState.Stopped;
536        StopResultPolling();
537        OnStopped();
538      }
539    }
540
541    private bool AllJobsFinished() {
542      return HiveJob.GetAllHiveJobs().All(hj => hj.IsFinishedOptimizerDownloaded);
543    }
544
545    void jobResultPoller_ExceptionOccured(object sender, EventArgs<Exception> e) {
546      OnExceptionOccured(e.Value);
547    }
548    #endregion
549
550    #region Execution Time Timer
551    private void InitTimer() {
552      timer = new System.Timers.Timer(100);
553      timer.AutoReset = true;
554      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
555    }
556
557    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
558      DateTime now = DateTime.Now;
559      ExecutionTime += now - lastUpdateTime;
560      lastUpdateTime = now;
561    }
562    #endregion
563
564    #region Logging
565    private void LogMessage(string message) {
566      // HeuristicLab.Log is not Thread-Safe, so lock on every call
567      lock (locker) {
568        log.LogMessage(message);
569        Logger.Debug(message);
570      }
571    }
572
573    private void LogMessage(Guid jobId, string message) {
574      //GetJobItemById(jobId).LogMessage(message);
575      LogMessage(message + " (jobId: " + jobId + ")");
576    }
577
578    #endregion
579
580    /// <summary>
581    /// Downloads the root job from hive and sets the experiment, rootJob and rootJobItem
582    /// </summary>
583    public void LoadHiveJob() {
584      progress = new Progress();
585      try {
586        IsProgressing = true;
587        int totalJobCount = 0;
588        int jobCount = 0;
589        progress.Status = "Connecting to Server...";
590        using (var service = ServiceLocator.Instance.GetService()) {
591          // fetch all Job objects to create the full tree of tree of HiveJob objects
592          progress.Status = "Downloading list of jobs...";
593          IEnumerable<LightweightJob> allResults = service.Obj.GetLightweightChildJobs(rootJobId, true, true);
594          totalJobCount = allResults.Count();
595
596          // download them first
597          IDictionary<Guid, Job> allJobs = new Dictionary<Guid, Job>();
598          IDictionary<Guid, JobData> allJobDatas = new Dictionary<Guid, JobData>();
599          foreach (LightweightJob lightweightJob in allResults) {
600            jobCount++;
601            progress.Status = string.Format("Downloading {0} of {1} jobs...", jobCount, totalJobCount);
602            allJobs.Add(lightweightJob.Id, service.Obj.GetJob(lightweightJob.Id));
603            allJobDatas.Add(lightweightJob.Id, service.Obj.GetJobData(lightweightJob.Id));
604            progress.ProgressValue = (double)jobCount / totalJobCount;
605          }
606
607          jobCount = 1;
608          progress.Status = string.Format("Deserializing {0} of {1} jobs... ({2} kb)", jobCount, totalJobCount, allJobDatas[this.rootJobId].Data.Count() / 1024);
609          this.HiveJob = new HiveJob(allJobs[this.rootJobId], allJobDatas[this.rootJobId], false);
610          allJobDatas.Remove(this.rootJobId); // reduce memory footprint
611          allJobs.Remove(this.rootJobId);
612          progress.ProgressValue = (double)jobCount / totalJobCount;
613
614          if (this.HiveJob.Job.DateFinished.HasValue) {
615            this.ExecutionTime = this.HiveJob.Job.DateFinished.Value - this.HiveJob.Job.DateCreated;
616            this.lastUpdateTime = this.HiveJob.Job.DateFinished.Value;
617            this.ExecutionState = Core.ExecutionState.Stopped;
618            OnStopped();
619          } else {
620            this.ExecutionTime = DateTime.Now - this.HiveJob.Job.DateCreated;
621            this.lastUpdateTime = DateTime.Now;
622            this.ExecutionState = Core.ExecutionState.Started;
623            OnStarted();
624          }
625
626          // build child-job tree
627          LoadChildResults(service.Obj, this.HiveJob, allResults, allJobs, allJobDatas, progress, totalJobCount, ref jobCount);
628          StartResultPolling();
629        }
630      }
631      catch (Exception e) {
632        OnExceptionOccured(e);
633      }
634      finally {
635        IsProgressing = false;
636      }
637    }
638
639    private void LoadChildResults(IHiveService service, HiveJob parentHiveJob, IEnumerable<LightweightJob> allResults, IDictionary<Guid, Job> allJobs, IDictionary<Guid, JobData> allJobDatas, IProgress progress, int totalJobCount, ref int jobCount) {
640      IEnumerable<LightweightJob> childResults = from result in allResults
641                                                 where result.ParentJobId.HasValue && result.ParentJobId.Value == parentHiveJob.Job.Id
642                                                 orderby result.DateCreated ascending
643                                                 select result;
644      foreach (LightweightJob lightweightJob in childResults) {
645        jobCount++;
646        progress.Status = string.Format("Deserializing {0} of {1} jobs ({2} kb)...", jobCount, totalJobCount, allJobDatas[lightweightJob.Id].Data.Count() / 1024);
647        OptimizerJob optimizerJob = null;
648        try {
649          optimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(allJobDatas[lightweightJob.Id].Data);
650        }
651        catch {
652          optimizerJob = null;
653        }
654        progress.ProgressValue = (double)jobCount / totalJobCount;
655        HiveJob childHiveJob = new HiveJob(optimizerJob, false);
656        parentHiveJob.AddChildHiveJob(childHiveJob);
657        childHiveJob.Job = allJobs[lightweightJob.Id];
658        allJobDatas.Remove(lightweightJob.Id); // reduce memory footprint
659        allJobs.Remove(lightweightJob.Id);
660        if (jobCount % 10 == 0) GC.Collect(); // this is needed or otherwise HL takes over the system when the number of jobs is high
661        LoadChildResults(service, childHiveJob, allResults, allJobs, allJobDatas, progress, totalJobCount, ref jobCount);
662      }
663    }
664
665    private OptimizerJob LoadOptimizerJob(Guid jobId) {
666      using (var service = ServiceLocator.Instance.GetService()) {
667        JobData jobData = service.Obj.GetJobData(jobId);
668        try {
669          return PersistenceUtil.Deserialize<OptimizerJob>(jobData.Data);
670        }
671        catch {
672          return null;
673        }
674      }
675    }
676   
677  }
678}
Note: See TracBrowser for help on using the repository browser.