Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1233

  • use mac address as Guid for Slaves (for now...)
  • Slave Windows Service now also works if it can't write to an event source
File size: 8.1 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      //TODO: how to display connectedsince in gui?
68      //hardwareInfo.Login = WcfService.Instance.ConnectedSince;
69      return slave;
70    }
71
72    /// <summary>
73    /// collects and returns information that get displayed by the Client Console
74    /// </summary>
75    /// <returns></returns>
76    public StatusCommons GetStatusForClientConsole() {
77      //Todo: Locking
78      StatusCommons st = new StatusCommons();
79      st.ClientGuid = slave.Id;
80
81      st.Status = WcfService.Instance.ConnState;
82      st.ConnectedSince = WcfService.Instance.ConnectedSince;
83
84      st.TotalCores = slave.Cores.HasValue ? slave.Cores.Value : 0;
85      st.FreeCores = slave.Cores.HasValue ? slave.Cores.Value - GetUsedCores() : 0;
86
87      st.JobsAborted = SlaveStatusInfo.JobsAborted;
88      st.JobsDone = SlaveStatusInfo.JobsProcessed;
89      st.JobsFetched = SlaveStatusInfo.JobsFetched;
90
91      Dictionary<Guid, Executor> engines = Core.ExecutionEngines;
92      st.Jobs = new List<JobStatus>();
93
94      lock (engines) {
95        foreach (KeyValuePair<Guid, Executor> kvp in engines) {
96          Executor e = kvp.Value;
97          st.Jobs.Add(new JobStatus { JobId = e.JobId, ExecutionTime = e.ExecutionTime, Since = e.CreationTime });
98        }
99      }
100      return st;
101    }
102
103    public Dictionary<Guid, TimeSpan> GetExecutionTimeOfAllJobs() {
104      Dictionary<Guid, TimeSpan> prog = new Dictionary<Guid, TimeSpan>();
105      Dictionary<Guid, Executor> engines = Core.ExecutionEngines;
106      lock (engines) {
107        foreach (KeyValuePair<Guid, Executor> kvp in engines) {
108          Executor e = kvp.Value;
109          prog[e.JobId] = e.ExecutionTime;
110        }
111      }
112      return prog;
113    }
114
115    public int GetUsedCores() {
116      Dictionary<Guid, Executor> engines = Core.ExecutionEngines;
117      Dictionary<Guid, Job> jobs = Core.Jobs;
118      int usedCores = 0;
119      lock (engines) {
120        foreach (KeyValuePair<Guid, Job> kvp in jobs)
121          usedCores += kvp.Value.CoresNeeded;
122      }
123      return usedCores;
124    }
125
126    public static Guid GetUniqueMachineId() {
127      if (Settings.Default.Guid == Guid.Empty) {
128        Guid id;
129        try {
130          id = GetUniqueMachineIdFromMac();
131        }
132        catch {
133          // fallback if something goes wrong...       
134          id = Guid.NewGuid();
135        }
136
137        Settings.Default.Guid = id;
138        Settings.Default.Save();
139        return id;
140      } else
141        return Settings.Default.Guid;
142    }
143
144    /// <summary>
145    /// MegaBytes
146    /// </summary>
147    private static int? GetPhysicalMemory() {
148      long? res = GetWMIValue("Win32_ComputerSystem", "TotalPhysicalMemory");
149      if (res != null)
150        return (int)(res / 1024 / 1024);
151      else
152        return null;
153    }
154
155    /// <summary>
156    /// Mhz
157    /// </summary>
158    private static int? GetCpuSpeed() {
159      return (int)GetWMIValue("Win32_Processor", "MaxClockSpeed");
160    }
161
162    /// <summary>
163    /// Generate a guid based on mac address of the first found nic (yes, mac addresses are not unique...).
164    /// Format:
165    ///
166    ///  D1      D2  D3  Res.   D4
167    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
168    /// |0 0 0 0|0 0|0 0|0 0 mac address|
169    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
170    ///
171    /// The mac address is saved in the last 48 bits of the Data 4 segment
172    /// of the guid (first 2 bytes of Data 4 are reserved).
173    /// </summary>   
174    private static Guid GetUniqueMachineIdFromMac() {
175      ManagementClass mgtClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
176      ManagementObjectCollection mgtCol = mgtClass.GetInstances();
177
178      foreach (ManagementObject mgtObj in mgtCol) {
179        foreach (var prop in mgtObj.Properties) {
180          if (prop.Value != null && prop.Name == "MACAddress") {
181            try {
182              //simply take the first nic
183              string mac = prop.Value.ToString();
184              byte[] b = new byte[8];
185              string[] macParts = mac.Split(':');
186              if (macParts.Length == 6) {
187                for (int i = 0; i < macParts.Length; i++) {
188                  b[i + 2] = (byte)((ParseNybble(macParts[i][0]) << 4) | ParseNybble(macParts[i][1]));
189                }
190
191                Guid guid = new Guid(0, 0, 0, b);
192                return guid;
193              } else
194                throw new Exception("Error getting mac addresse");
195            }
196            catch {
197              throw new Exception("Error getting mac addresse");
198            }
199          }
200        }
201      }
202      throw new Exception("Error getting mac addresse");
203    }
204
205    /// <summary>
206    /// return numeric value of a single hex-char
207    /// (see: http://stackoverflow.com/questions/854012/how-to-convert-hex-to-a-byte-array)
208    /// </summary>   
209    static int ParseNybble(char c) {
210      if (c >= '0' && c <= '9') {
211        return c - '0';
212      }
213      if (c >= 'A' && c <= 'F') {
214        return c - 'A' + 10;
215      }
216      if (c >= 'a' && c <= 'f') {
217        return c - 'a' + 10;
218      }
219      throw new ArgumentException("Invalid hex digit: " + c);
220    }
221
222    private static long? GetWMIValue(string clazz, string property) {
223      ManagementClass mgtClass = new ManagementClass(clazz);
224      ManagementObjectCollection mgtCol = mgtClass.GetInstances();
225
226      foreach (ManagementObject mgtObj in mgtCol) {
227        foreach (var prop in mgtObj.Properties) {
228          if (prop.Value != null && prop.Name == property) {
229            try {
230              return long.Parse(prop.Value.ToString());
231            }
232            catch {
233              return null;
234            }
235          }
236        }
237      }
238      return null;
239    }
240
241    public static int GetFreeMemory() {
242      PerformanceCounter counter = new PerformanceCounter("Memory", "Available Bytes", true);
243      int mb = (int)(counter.NextValue() / 1024 / 1024);
244      return mb;
245    }
246  }
247}
Note: See TracBrowser for help on using the repository browser.