Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

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