Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

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