Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

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