Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave/3.4/ConfigManager.cs @ 5789

Last change on this file since 5789 was 5789, checked in by ascheibe, 13 years ago

#1233

  • added autostart for tray icon to installer
  • machine unique id now includes the machine name
  • core: check if job already exists on slave
  • already finished jobs now fail and are sent back
File size: 8.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Diagnostics;
25using System.Management;
26using HeuristicLab.Clients.Hive.SlaveCore.Properties;
27
28
29namespace HeuristicLab.Clients.Hive.SlaveCore {
30  /// <summary>
31  /// accesses the server and sends his data (uuid, uptimes, hardware config)
32  /// </summary>
33  public class ConfigManager {
34    private static ConfigManager instance = null;
35    public static ConfigManager Instance {
36      get {
37        if (instance == null) {
38          instance = new ConfigManager();
39        }
40        return instance;
41      }
42    }
43
44    public Core Core { get; set; }
45    private Slave slave;
46
47    /// <summary>
48    /// Constructor for the singleton, must recover Guid, Calendar, ...
49    /// </summary>
50    private ConfigManager() {
51      slave = new Slave();
52      slave.Id = GetUniqueMachineId();
53      slave.Name = Environment.MachineName;
54      slave.Cores = Environment.ProcessorCount;
55      slave.Memory = GetPhysicalMemory();
56      slave.CpuArchitecture = Environment.Is64BitOperatingSystem ? CpuArchitecture.x64 : CpuArchitecture.x86;
57      slave.OperatingSystem = Environment.OSVersion.VersionString;
58      slave.CpuSpeed = GetCpuSpeed();
59      slave.FreeMemory = GetFreeMemory();
60    }
61
62    /// <summary>
63    /// Get all the Information about the client
64    /// </summary>
65    /// <returns>the ClientInfo object</returns>
66    public Slave GetClientInfo() {
67      return slave;
68    }
69
70    /// <summary>
71    /// collects and returns information that get displayed by the Client Console
72    /// </summary>
73    /// <returns></returns>
74    public StatusCommons GetStatusForClientConsole() {
75      StatusCommons st = new StatusCommons();
76      st.ClientGuid = slave.Id;
77
78      st.Status = WcfService.Instance.ConnState;
79      st.ConnectedSince = WcfService.Instance.ConnectedSince;
80
81      st.TotalCores = slave.Cores.HasValue ? slave.Cores.Value : 0;
82      st.FreeCores = slave.Cores.HasValue ? slave.Cores.Value - GetUsedCores() : 0;
83
84      st.JobsAborted = SlaveStatusInfo.JobsAborted;
85      st.JobsDone = SlaveStatusInfo.JobsProcessed;
86      st.JobsFetched = SlaveStatusInfo.JobsFetched;
87
88      Dictionary<Guid, Executor> engines = Core.ExecutionEngines;
89      st.Jobs = new List<JobStatus>();
90
91      lock (engines) {
92        foreach (KeyValuePair<Guid, Executor> kvp in engines) {
93          Executor e = kvp.Value;
94          st.Jobs.Add(new JobStatus { JobId = e.JobId, ExecutionTime = e.ExecutionTime, Since = e.CreationTime });
95        }
96      }
97      return st;
98    }
99
100    public Dictionary<Guid, TimeSpan> GetExecutionTimeOfAllJobs() {
101      Dictionary<Guid, TimeSpan> prog = new Dictionary<Guid, TimeSpan>();
102      Dictionary<Guid, Executor> engines = Core.ExecutionEngines;
103      lock (engines) {
104        foreach (KeyValuePair<Guid, Executor> kvp in engines) {
105          Executor e = kvp.Value;
106          prog[e.JobId] = e.ExecutionTime;
107        }
108      }
109      return prog;
110    }
111
112    public int GetUsedCores() {
113      Dictionary<Guid, Executor> engines = Core.ExecutionEngines;
114      Dictionary<Guid, Job> jobs = Core.Jobs;
115      int usedCores = 0;
116      lock (engines) {
117        foreach (KeyValuePair<Guid, Job> kvp in jobs)
118          usedCores += kvp.Value.CoresNeeded;
119      }
120      return usedCores;
121    }
122
123    public static Guid GetUniqueMachineId() {
124      if (Settings.Default.Guid == Guid.Empty) {
125        Guid id;
126        try {
127          id = GetUniqueMachineIdFromMac();
128        }
129        catch {
130          // fallback if something goes wrong...       
131          id = Guid.NewGuid();
132        }
133
134        Settings.Default.Guid = id;
135        Settings.Default.Save();
136        return id;
137      } else
138        return Settings.Default.Guid;
139    }
140
141    /// <summary>
142    /// returns total physical memory of the machine in MB
143    /// </summary>
144    private static int? GetPhysicalMemory() {
145      long? res = GetWMIValue("Win32_ComputerSystem", "TotalPhysicalMemory");
146      if (res != null)
147        return (int)(res / 1024 / 1024);
148      else
149        return null;
150    }
151
152    /// <summary>
153    /// returns CPU frequence of the machine in Mhz
154    /// </summary>
155    private static int? GetCpuSpeed() {
156      return (int)GetWMIValue("Win32_Processor", "MaxClockSpeed");
157    }
158
159    /// <summary>
160    /// Generate a guid based on mac address of the first found nic (yes, mac addresses are not unique...).
161    /// Format:
162    ///
163    ///  D1      D2  D3  Res.   D4
164    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165    /// |0 0 0 0|0 0|0 0|0 0 mac address|
166    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167    ///
168    /// The mac address is saved in the last 48 bits of the Data 4 segment
169    /// of the guid (first 2 bytes of Data 4 are reserved).
170    /// </summary>   
171    private static Guid GetUniqueMachineIdFromMac() {
172      ManagementClass mgtClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
173      ManagementObjectCollection mgtCol = mgtClass.GetInstances();
174
175      foreach (ManagementObject mgtObj in mgtCol) {
176        foreach (var prop in mgtObj.Properties) {
177          if (prop.Value != null && prop.Name == "MACAddress") {
178            try {
179              //simply take the first nic
180              string mac = prop.Value.ToString();
181              byte[] b = new byte[8];
182              string[] macParts = mac.Split(':');
183              if (macParts.Length == 6) {
184                for (int i = 0; i < macParts.Length; i++) {
185                  b[i + 2] = (byte)((ParseNybble(macParts[i][0]) << 4) | ParseNybble(macParts[i][1]));
186                }
187
188                // also get machine name and save it to the first 4 bytes               
189                Guid guid = new Guid(Environment.MachineName.GetHashCode(), 0, 0, b);
190                return guid;
191              } else
192                throw new Exception("Error getting mac addresse");
193            }
194            catch {
195              throw new Exception("Error getting mac addresse");
196            }
197          }
198        }
199      }
200      throw new Exception("Error getting mac addresse");
201    }
202
203    /// <summary>
204    /// return numeric value of a single hex-char
205    /// (see: http://stackoverflow.com/questions/854012/how-to-convert-hex-to-a-byte-array)
206    /// </summary>   
207    static int ParseNybble(char c) {
208      if (c >= '0' && c <= '9') {
209        return c - '0';
210      }
211      if (c >= 'A' && c <= 'F') {
212        return c - 'A' + 10;
213      }
214      if (c >= 'a' && c <= 'f') {
215        return c - 'a' + 10;
216      }
217      throw new ArgumentException("Invalid hex digit: " + c);
218    }
219
220    private static long? GetWMIValue(string clazz, string property) {
221      ManagementClass mgtClass = new ManagementClass(clazz);
222      ManagementObjectCollection mgtCol = mgtClass.GetInstances();
223
224      foreach (ManagementObject mgtObj in mgtCol) {
225        foreach (var prop in mgtObj.Properties) {
226          if (prop.Value != null && prop.Name == property) {
227            try {
228              return long.Parse(prop.Value.ToString());
229            }
230            catch {
231              return null;
232            }
233          }
234        }
235      }
236      return null;
237    }
238
239    /// <summary>
240    /// returns free memory of machine in MB
241    /// </summary>   
242    public static int GetFreeMemory() {
243      int mb = 0;
244
245      try {
246        PerformanceCounter counter = new PerformanceCounter("Memory", "Available Bytes", true);
247        mb = (int)(counter.NextValue() / 1024 / 1024);
248      }
249      catch { }
250      return mb;
251    }
252  }
253}
Note: See TracBrowser for help on using the repository browser.