#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Diagnostics; using System.Management; namespace HeuristicLab.Clients.Hive.SlaveCore { /// /// accesses the server and sends his data (uuid, uptimes, hardware config) /// public class ConfigManager { private static ConfigManager instance = null; public static ConfigManager Instance { get { if (instance == null) { instance = new ConfigManager(); } return instance; } } /// /// if the Sleeping is true, the Slave won't accept any new jobs /// public bool Asleep { get; set; } public Core Core { get; set; } private Slave slave; private PerformanceCounter cpuCounter; /// /// Constructor for the singleton, must recover Guid, Calendar, ... /// private ConfigManager() { cpuCounter = new PerformanceCounter(); cpuCounter.CategoryName = "Processor"; cpuCounter.CounterName = "% Processor Time"; cpuCounter.InstanceName = "_Total"; Asleep = false; slave = new Slave(); slave.Id = GetUniqueMachineId(); slave.Name = Environment.MachineName; slave.Cores = Environment.ProcessorCount; slave.Memory = GetPhysicalMemory(); slave.CpuArchitecture = Environment.Is64BitOperatingSystem ? CpuArchitecture.x64 : CpuArchitecture.x86; slave.OperatingSystem = Environment.OSVersion.VersionString; slave.CpuSpeed = GetCpuSpeed(); slave.FreeMemory = GetFreeMemory(); } /// /// Get all the Information about the client /// /// the ClientInfo object public Slave GetClientInfo() { return slave; } public int GetFreeCores() { return slave.Cores.HasValue ? slave.Cores.Value - SlaveStatusInfo.UsedCores : 0; } /// /// collects and returns information that get displayed by the Client Console /// /// public StatusCommons GetStatusForClientConsole() { StatusCommons st = new StatusCommons(); st.ClientGuid = slave.Id; st.Status = WcfService.Instance.ConnState; st.ConnectedSince = WcfService.Instance.ConnectedSince; st.TotalCores = slave.Cores.HasValue ? slave.Cores.Value : 0; st.FreeCores = GetFreeCores(); st.Asleep = ConfigManager.Instance.Asleep; st.JobsAborted = SlaveStatusInfo.JobsAborted; st.JobsFinished = SlaveStatusInfo.JobsFinished; st.JobsFetched = SlaveStatusInfo.JobsFetched; st.JobsFailed = SlaveStatusInfo.JobsFailed; Dictionary slaveJobs = Core.SlaveJobs; st.Jobs = new List(); lock (slaveJobs) { foreach (KeyValuePair kvp in slaveJobs) { Executor e = kvp.Value.JobExecutor; if (e != null && !kvp.Value.Finished) { st.Jobs.Add(new JobStatus { JobId = e.JobId, ExecutionTime = e.ExecutionTime, Since = e.CreationTime }); } } } return st; } public Dictionary GetExecutionTimeOfAllJobs() { Dictionary prog = new Dictionary(); Dictionary slaveJobs = Core.SlaveJobs; lock (slaveJobs) { foreach (KeyValuePair kvp in slaveJobs) { Executor e = kvp.Value.JobExecutor; if (e != null && !kvp.Value.Finished) { //don't include jobs in hb's which are currently serializing if (e.SendHeartbeatForExecutor) { prog[e.JobId] = e.ExecutionTime; } } } } return prog; } public static Guid GetUniqueMachineId() { Guid id; try { id = GetUniqueMachineIdFromMac(); } catch { // fallback if something goes wrong... id = new Guid(Environment.MachineName.GetHashCode(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } return id; } /// /// returns total physical memory of the machine in MB /// private static int? GetPhysicalMemory() { long? res = GetWMIValue("Win32_ComputerSystem", "TotalPhysicalMemory"); if (res != null) return (int)(res / 1024 / 1024); else return null; } /// /// returns CPU frequence of the machine in Mhz /// private static int? GetCpuSpeed() { return (int)GetWMIValue("Win32_Processor", "MaxClockSpeed"); } /// /// Generate a guid based on mac address of the first found nic (yes, mac addresses are not unique...). /// Format: /// /// D1 D2 D3 Res. D4 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /// |n a m e|0 0|0 0|0 0 mac address| /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /// /// The mac address is saved in the last 48 bits of the Data 4 segment /// of the guid (first 2 bytes of Data 4 are reserved). /// D1 contains the name of the machine. /// private static Guid GetUniqueMachineIdFromMac() { ManagementClass mgtClass = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection mgtCol = mgtClass.GetInstances(); foreach (ManagementObject mgtObj in mgtCol) { foreach (var prop in mgtObj.Properties) { if (prop.Value != null && prop.Name == "MACAddress") { try { //simply take the first nic string mac = prop.Value.ToString(); byte[] b = new byte[8]; string[] macParts = mac.Split(':'); if (macParts.Length == 6) { for (int i = 0; i < macParts.Length; i++) { b[i + 2] = (byte)((ParseNybble(macParts[i][0]) << 4) | ParseNybble(macParts[i][1])); } // also get machine name and save it to the first 4 bytes Guid guid = new Guid(Environment.MachineName.GetHashCode(), 0, 0, b); return guid; } else throw new Exception("Error getting mac addresse"); } catch { throw new Exception("Error getting mac addresse"); } } } } throw new Exception("Error getting mac addresse"); } /// /// return numeric value of a single hex-char /// (see: http://stackoverflow.com/questions/854012/how-to-convert-hex-to-a-byte-array) /// static int ParseNybble(char c) { if (c >= '0' && c <= '9') { return c - '0'; } if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } throw new ArgumentException("Invalid hex digit: " + c); } private static long? GetWMIValue(string clazz, string property) { ManagementClass mgtClass = new ManagementClass(clazz); ManagementObjectCollection mgtCol = mgtClass.GetInstances(); foreach (ManagementObject mgtObj in mgtCol) { foreach (var prop in mgtObj.Properties) { if (prop.Value != null && prop.Name == property) { try { return long.Parse(prop.Value.ToString()); } catch { return null; } } } } return null; } /// /// returns free memory of machine in MB /// public static int GetFreeMemory() { int mb = 0; try { PerformanceCounter counter = new PerformanceCounter("Memory", "Available Bytes", true); mb = (int)(counter.NextValue() / 1024 / 1024); } catch { } return mb; } public float GetCpuUtilization() { return cpuCounter.NextValue(); } } }