Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/PluginCache.cs @ 5707

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

#1260

  • some changes due to the removal of Disposable (r5706)
  • copy PluginInfrastructure files into PluginCache folder in slaves (needed due to r5703)
File size: 8.0 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.IO;
25using System.Linq;
26using System.Reflection;
27using System.Runtime.CompilerServices;
28using System.Threading;
29using HeuristicLab.Hive.Contracts.BusinessObjects;
30using HeuristicLab.Hive.Slave.Communication;
31using HeuristicLab.PluginInfrastructure;
32using HeuristicLab.PluginInfrastructure.Manager;
33
34namespace HeuristicLab.Hive.Slave.Core {
35  public class PluginCache {
36    private static object locker = new object();
37    public const string ConfigFileName = "Sandbox.config";
38
39    private static PluginCache instance = null;
40
41    public string PluginCacheDir { get; set; }
42    public string PluginTempBaseDir { get; set; }
43
44    private List<PluginDescription> cachedPlugins = new List<PluginDescription>();
45
46    private PluginManager pm;
47
48    public static PluginCache Instance {
49      get {
50        if (instance == null)
51          instance = new PluginCache();
52        return instance;
53      }
54    }
55
56    public string ConfigFilePath {
57      get {
58        return Path.Combine(PluginCacheDir, ConfigFileName);
59      }
60    }
61
62    public PluginCache() {
63      PluginCacheDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PluginCache");
64      PluginTempBaseDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PluginTemp");
65
66      this.pm = new PluginManager(PluginCacheDir);
67      DoUpdateRun();
68    }
69
70    private void DoUpdateRun() {
71      if (!Directory.Exists(PluginCacheDir)) {
72        Directory.CreateDirectory(PluginCacheDir);
73        string baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
74        CopyPluginInfrastructureFiles(baseDir, PluginCacheDir);
75      }
76      pm.DiscoverAndCheckPlugins();
77      cachedPlugins = new List<PluginDescription>(pm.Plugins);
78    }
79
80    [MethodImpl(MethodImplOptions.Synchronized)]
81    public void CopyPluginsForJob(List<HivePluginInfoDto> requests, Guid jobId) {
82      lock (locker) {
83        String targetDir = Path.Combine(PluginTempBaseDir, jobId.ToString());
84
85        if (Directory.Exists(targetDir)) {
86          Directory.Delete(targetDir, true);
87        }
88
89        DirectoryInfo di = Directory.CreateDirectory(targetDir);
90
91        foreach (HivePluginInfoDto requestedPlugin in requests) {
92          PluginDescription pd = cachedPlugins.Where(cp =>
93            cp.Name == requestedPlugin.Name &&
94            cp.Version.Major == requestedPlugin.Version.Major &&
95            cp.Version.Minor == requestedPlugin.Version.Minor).SingleOrDefault();
96          if (pd != null) {
97            foreach (IPluginFile ipf in pd.Files) {
98              File.Copy(ipf.Name, Path.Combine(targetDir, Path.GetFileName(ipf.Name)));
99            }
100          }
101        }
102
103        // copy config file
104        File.Copy(ConfigFilePath, Path.Combine(targetDir, ConfigFileName));
105
106        // copy files from PluginInfrastructure, which are not declared
107        string baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
108        CopyPluginInfrastructureFiles(baseDir, targetDir);
109
110        // copy slave plugins, otherwise its not possible to register the UnhandledException handler to the appdomain
111        CopySlaveFiles(baseDir, targetDir);
112      }
113    }
114
115    private void CopySlaveFiles(string sourceDir, String targetDir) {
116      CopyFile(sourceDir, targetDir, "HeuristicLab.Hive.Slave.Core-3.3.dll");
117      CopyFile(sourceDir, targetDir, "HeuristicLab.Hive.Slave.Common-3.3.dll");
118      CopyFile(sourceDir, targetDir, "HeuristicLab.Hive.Slave.Communication-3.3.dll");
119      CopyFile(sourceDir, targetDir, "HeuristicLab.Hive.Slave.ExecutionEngine-3.3.dll");
120    }
121
122    private void CopyPluginInfrastructureFiles(string sourceDir, String targetDir) {
123      CopyFile(sourceDir, targetDir, "HeuristicLab.PluginInfrastructure-3.3.dll");
124      CopyFile(sourceDir, targetDir, "ICSharpCode.SharpZipLib.dll");
125      CopyFile(sourceDir, targetDir, "ICSharpCode.SharpZipLib License.txt");
126    }
127
128    private void CopyFile(string baseDir, string targetDir, string fileName) {
129      if (!File.Exists(Path.Combine(targetDir, fileName))) File.Copy(Path.Combine(baseDir, fileName), Path.Combine(targetDir, fileName));
130    }
131
132    [MethodImpl(MethodImplOptions.Synchronized)]
133    internal void PreparePlugins(List<HivePluginInfoDto> requiredPlugins) {
134      lock (locker) {
135        Logger.Debug("Fetching plugins for job");
136        List<HivePluginInfoDto> localPlugins = new List<HivePluginInfoDto>();
137        List<HivePluginInfoDto> missingPlugins = new List<HivePluginInfoDto>();
138        bool found = false;
139
140        foreach (HivePluginInfoDto info in requiredPlugins) {
141          //we MAY run in problems here - if there is a plugin twice in requests, there may be added two different versions of the plugin
142          foreach (PluginDescription cachedPlugin in cachedPlugins) {
143            if (info.Name == cachedPlugin.Name && info.Version == cachedPlugin.Version) {
144              localPlugins.Add(new HivePluginInfoDto() { Id = new Guid(), Name = info.Name, Version = info.Version, Update = true });
145              found = true;
146
147              break;
148            }
149          }
150          if (!found) {
151            Logger.Debug("Plugin NOT found " + info.Name + ", " + info.Version);
152            missingPlugins.Add(info);
153          }
154          found = false;
155        }
156
157        Logger.Debug("First run - Update the plugins in the cache");
158        localPlugins.AddRange(missingPlugins);
159        IEnumerable<CachedHivePluginInfoDto> updateablePlugins = WcfService.Instance.RequestPlugins(missingPlugins);
160
161        foreach (CachedHivePluginInfoDto updateablePlugin in updateablePlugins) {
162          PluginDescription pd = cachedPlugins.Where(cachedPlugin =>
163            cachedPlugin.Name == updateablePlugin.Name &&
164            cachedPlugin.Version.Major == updateablePlugin.Version.Major &&
165            cachedPlugin.Version.Minor == updateablePlugin.Version.Major).SingleOrDefault();
166
167          if (pd != null) {
168            foreach (IPluginFile ipf in pd.Files) {
169              Logger.Debug(string.Format("deleting {0}", Path.GetFileName(ipf.Name)));
170              File.Delete(ipf.Name);
171            }
172          }
173
174          foreach (HivePluginFile pf in updateablePlugin.PluginFiles) {
175            Logger.Debug(string.Format("writing {0}", Path.GetFileName(pf.Name)));
176            File.WriteAllBytes(Path.Combine(PluginCacheDir, Path.GetFileName(pf.Name)), pf.BinaryFile);
177          }
178        }
179
180        // download config file
181        HivePluginFile configFile = WcfService.Instance.GetConfigurationFile();
182        File.WriteAllBytes(ConfigFilePath, configFile.BinaryFile);
183
184        DoUpdateRun();
185      }
186    }
187
188    internal void DeletePluginsForJob(Guid id) {
189      try {
190        Logger.Debug("unloading...");
191        int tries = 5;
192        while (tries > 0) {
193          try {
194            Directory.Delete(Path.Combine(PluginTempBaseDir, id.ToString()), true);
195            tries = 0;
196          }
197          catch {
198            Thread.Sleep(1000);
199            tries--;
200            if (tries == 0) throw;
201          }
202        }
203      }
204      catch (Exception ex) {
205        Logger.Debug("failed while unloading " + id + " with exception " + ex);
206      }
207    }
208
209
210  }
211}
Note: See TracBrowser for help on using the repository browser.