Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveStatistics/sources/HeuristicLab.Clients.Hive.Slave/3.3/Manager/ConfigManager.cs @ 12395

Last change on this file since 12395 was 12395, checked in by dglaser, 10 years ago

#2388 merged trunk into hive statistics branch

File size: 8.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Linq;
26using System.Management;
27using System.Net.NetworkInformation;
28using HeuristicLab.Clients.Hive.SlaveCore.Properties;
29
30
31namespace HeuristicLab.Clients.Hive.SlaveCore {
32  /// <summary>
33  /// accesses the server and sends his data (uuid, uptimes, hardware config)
34  /// </summary>
35  public class ConfigManager {
36    private static ConfigManager instance = null;
37    private const string vmwareNameString = "VMware";
38    private const string virtualboxNameString = "VirtualBox";
39    private const int macLength = 6;
40    private const int macLongLength = 8;
41
42    public static ConfigManager Instance {
43      get { return instance; }
44      set { instance = value; }
45    }
46
47    /// <summary>
48    /// if Asleep is true, the Slave won't accept any new jobs
49    /// </summary>
50    public bool Asleep { get; set; }
51    private TaskManager jobManager;
52    private Slave slave;
53    private PerformanceCounter cpuCounter;
54    private PerformanceCounter memCounter;
55
56    /// <summary>
57    /// Constructor for the singleton, must recover Guid, Calendar, ...
58    /// </summary>
59    public ConfigManager(TaskManager jobManager) {
60      this.jobManager = jobManager;
61      cpuCounter = new PerformanceCounter();
62      cpuCounter.CategoryName = "Processor";
63      cpuCounter.CounterName = "% Processor Time";
64      cpuCounter.InstanceName = "_Total";
65      memCounter = new PerformanceCounter("Memory", "Available Bytes", true);
66
67      Asleep = false;
68      slave = new Slave();
69      slave.Id = GetUniqueMachineId();
70      slave.Name = Environment.MachineName;
71      if (Settings.Default.NrOfCoresToScavenge < 1 || Settings.Default.NrOfCoresToScavenge > Environment.ProcessorCount) {
72        slave.Cores = Environment.ProcessorCount;
73      } else {
74        slave.Cores = Settings.Default.NrOfCoresToScavenge;
75      }
76      slave.Memory = GetPhysicalMemory();
77      slave.CpuArchitecture = Environment.Is64BitOperatingSystem ? CpuArchitecture.x64 : CpuArchitecture.x86;
78      slave.OperatingSystem = Environment.OSVersion.VersionString;
79      slave.CpuSpeed = GetCpuSpeed();
80      slave.IsDisposable = true;
81
82      UpdateSlaveInfo();
83    }
84
85    private void UpdateSlaveInfo() {
86      if (slave != null) {
87        slave.FreeMemory = GetFreeMemory();
88        slave.HbInterval = (int)Settings.Default.HeartbeatInterval.TotalSeconds;
89      }
90    }
91
92    /// <summary>
93    /// Get all the Information about the client
94    /// </summary>
95    /// <returns>the ClientInfo object</returns>
96    public Slave GetClientInfo() {
97      UpdateSlaveInfo();
98      return slave;
99    }
100
101    public int GetFreeCores() {
102      return slave.Cores.HasValue ? slave.Cores.Value - SlaveStatusInfo.UsedCores : 0;
103    }
104
105    /// <summary>
106    /// collects and returns information that get displayed by the Client Console
107    /// </summary>
108    /// <returns></returns>
109    public StatusCommons GetStatusForClientConsole() {
110      StatusCommons st = new StatusCommons();
111      st.ClientGuid = slave.Id;
112
113      st.Status = WcfService.Instance.ConnState;
114      st.ConnectedSince = WcfService.Instance.ConnectedSince;
115
116      st.TotalCores = slave.Cores.HasValue ? slave.Cores.Value : 0;
117      st.FreeCores = GetFreeCores();
118      st.Asleep = this.Asleep;
119
120      st.JobsStarted = SlaveStatusInfo.TasksStarted;
121      st.JobsAborted = SlaveStatusInfo.TasksAborted;
122      st.JobsFinished = SlaveStatusInfo.TasksFinished;
123      st.JobsFetched = SlaveStatusInfo.TasksFetched;
124      st.JobsFailed = SlaveStatusInfo.TasksFailed;
125
126      st.Jobs = jobManager.GetExecutionTimes().Select(x => new TaskStatus { TaskId = x.Key, ExecutionTime = x.Value }).ToList();
127
128      return st;
129    }
130
131    public Dictionary<Guid, TimeSpan> GetExecutionTimeOfAllJobs() {
132      Dictionary<Guid, TimeSpan> prog = new Dictionary<Guid, TimeSpan>();
133      try {
134        prog = jobManager.GetExecutionTimes();
135      }
136      catch (Exception ex) {
137        SlaveClientCom.Instance.LogMessage(string.Format("Exception was thrown while trying to get execution times: {0}", ex.Message));
138      }
139      return prog;
140    }
141
142    public static Guid GetUniqueMachineId() {
143      // mock slave id
144      return Guid.NewGuid();
145      /*
146      Guid id;
147
148      try {
149        id = GetUniqueMachineIdFromMac();
150      }
151      catch {
152        // fallback if something goes wrong...       
153        id = new Guid(Environment.MachineName.GetHashCode(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
154      }
155      return id;
156      */
157    }
158
159    /// <summary>
160    /// returns total physical memory of the machine in MB
161    /// </summary>
162    private static int? GetPhysicalMemory() {
163      long? res = GetWMIValue("Win32_ComputerSystem", "TotalPhysicalMemory");
164      if (res != null)
165        return (int)(res / 1024 / 1024);
166      else
167        return null;
168    }
169
170    /// <summary>
171    /// returns CPU frequence of the machine in Mhz
172    /// </summary>
173    private static int? GetCpuSpeed() {
174      return (int)GetWMIValue("Win32_Processor", "MaxClockSpeed");
175    }
176
177    /// <summary>
178    /// Generate a guid based on mac address of the first found nic (yes, mac addresses are not unique...)
179    /// and the machine name.
180    /// Format:
181    ///
182    ///  D1      D2  D3  Res.   D4
183    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184    /// |n a m e|0 0|0 0|0 0 mac address|
185    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
186    ///
187    /// The mac address is saved in the last 48 bits of the Data 4 segment
188    /// of the guid (first 2 bytes of Data 4 are reserved).
189    /// D1 contains the hash of the machinename.
190    /// </summary>   
191    private static Guid GetUniqueMachineIdFromMac() {
192      //try to get a real network interface, not a virtual one
193      NetworkInterface validNic = NetworkInterface.GetAllNetworkInterfaces()
194                      .FirstOrDefault(x =>
195                                  !x.Name.Contains(vmwareNameString) &&
196                                  !x.Name.Contains(virtualboxNameString) &&
197                                  (x.NetworkInterfaceType == NetworkInterfaceType.Ethernet ||
198                                   x.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet));
199
200      if (validNic == default(NetworkInterface)) {
201        validNic = NetworkInterface.GetAllNetworkInterfaces().First();
202      }
203
204      byte[] addr = validNic.GetPhysicalAddress().GetAddressBytes();
205      if (addr.Length < macLength || addr.Length > macLongLength) {
206        throw new ArgumentException(string.Format("Error generating slave UID: MAC address has to have a length between {0} and {1} bytes. Actual MAC address is: {2}",
207              macLength, macLongLength, addr));
208      }
209
210      if (addr.Length < macLongLength) {
211        byte[] b = new byte[8];
212        Array.Copy(addr, 0, b, 2, addr.Length);
213        addr = b;
214      }
215
216      // also get machine name and save it to the first 4 bytes               
217      Guid guid = new Guid(Environment.MachineName.GetHashCode(), 0, 0, addr);
218      return guid;
219    }
220
221    private static long? GetWMIValue(string clazz, string property) {
222      ManagementClass mgtClass = new ManagementClass(clazz);
223      ManagementObjectCollection mgtCol = mgtClass.GetInstances();
224
225      foreach (ManagementObject mgtObj in mgtCol) {
226        foreach (var prop in mgtObj.Properties) {
227          if (prop.Value != null && prop.Name == property) {
228            try {
229              return long.Parse(prop.Value.ToString());
230            }
231            catch {
232              return null;
233            }
234          }
235        }
236      }
237      return null;
238    }
239
240    /// <summary>
241    /// returns free memory of machine in MB
242    /// </summary>   
243    public int GetFreeMemory() {
244      try {
245        return (int)(memCounter.NextValue() / 1024 / 1024);
246      }
247      catch {
248        return 0;
249      }
250    }
251
252    public float GetCpuUtilization() {
253      try {
254        return cpuCounter.NextValue();
255      }
256      catch {
257        return 0.0f;
258      }
259    }
260  }
261}
Note: See TracBrowser for help on using the repository browser.