source: branches/2520_PersistenceReintegration/HeuristicLab.Clients.Hive.Slave/3.3/Manager/ConfigManager.cs @ 16453

Last change on this file since 16453 was 16453, checked in by jkarder, 10 months ago

#2520: updated year of copyrights

File size: 8.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2019 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      Guid id;
144      try {
145        id = GetUniqueMachineIdFromMac();
146      }
147      catch {
148        // fallback if something goes wrong...       
149        id = new Guid(Environment.MachineName.GetHashCode(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
150      }
151      return id;
152    }
153
154    /// <summary>
155    /// returns total physical memory of the machine in MB
156    /// </summary>
157    private static int? GetPhysicalMemory() {
158      long? res = GetWMIValue("Win32_ComputerSystem", "TotalPhysicalMemory");
159      if (res != null)
160        return (int)(res / 1024 / 1024);
161      else
162        return null;
163    }
164
165    /// <summary>
166    /// returns CPU frequence of the machine in Mhz
167    /// </summary>
168    private static int? GetCpuSpeed() {
169      return (int)GetWMIValue("Win32_Processor", "MaxClockSpeed");
170    }
171
172    /// <summary>
173    /// Generate a guid based on mac address of the first found nic (yes, mac addresses are not unique...)
174    /// and the machine name.
175    /// Format:
176    ///
177    ///  D1      D2  D3  Res.   D4
178    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179    /// |n a m e|0 0|0 0|0 0 mac address|
180    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181    ///
182    /// The mac address is saved in the last 48 bits of the Data 4 segment
183    /// of the guid (first 2 bytes of Data 4 are reserved).
184    /// D1 contains the hash of the machinename.
185    /// </summary>   
186    private static Guid GetUniqueMachineIdFromMac() {
187      //try to get a real network interface, not a virtual one
188      NetworkInterface validNic = NetworkInterface.GetAllNetworkInterfaces()
189                      .FirstOrDefault(x =>
190                                  !x.Name.Contains(vmwareNameString) &&
191                                  !x.Name.Contains(virtualboxNameString) &&
192                                  (x.NetworkInterfaceType == NetworkInterfaceType.Ethernet ||
193                                   x.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet));
194
195      if (validNic == default(NetworkInterface)) {
196        validNic = NetworkInterface.GetAllNetworkInterfaces().First();
197      }
198
199      byte[] addr = validNic.GetPhysicalAddress().GetAddressBytes();
200      if (addr.Length < macLength || addr.Length > macLongLength) {
201        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}",
202              macLength, macLongLength, addr));
203      }
204
205      if (addr.Length < macLongLength) {
206        byte[] b = new byte[8];
207        Array.Copy(addr, 0, b, 2, addr.Length);
208        addr = b;
209      }
210
211      // also get machine name and save it to the first 4 bytes               
212      Guid guid = new Guid(Environment.MachineName.GetHashCode(), 0, 0, addr);
213      return guid;
214    }
215
216    private static long? GetWMIValue(string clazz, string property) {
217      ManagementClass mgtClass = new ManagementClass(clazz);
218      ManagementObjectCollection mgtCol = mgtClass.GetInstances();
219
220      foreach (ManagementObject mgtObj in mgtCol) {
221        foreach (var prop in mgtObj.Properties) {
222          if (prop.Value != null && prop.Name == property) {
223            try {
224              return long.Parse(prop.Value.ToString());
225            }
226            catch {
227              return null;
228            }
229          }
230        }
231      }
232      return null;
233    }
234
235    /// <summary>
236    /// returns free memory of machine in MB
237    /// </summary>   
238    public int GetFreeMemory() {
239      int mb = 0;
240
241      try {
242        mb = (int)(memCounter.NextValue() / 1024 / 1024);
243      }
244      catch { }
245      return mb;
246    }
247
248    public float GetCpuUtilization() {
249      float cpuVal = 0.0F;
250
251      try {
252        return cpuCounter.NextValue();
253      }
254      catch { }
255      return cpuVal;
256    }
257  }
258}
Note: See TracBrowser for help on using the repository browser.