#region License Information /* HeuristicLab * Copyright (C) 2002-2013 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.Linq; using System.Web.Mvc; using System.Web.Script.Serialization; using HeuristicLab.Services.Hive.DataAccess; namespace HeuristicLab.Services.Hive.Statistics.Controllers { //[OutputCache(Duration = 60 * 5)] public class ChartDataController : Controller { private static readonly TimeSpan DefaultDuration = new TimeSpan(1, 0, 0, 0); public JsonResult AverageCpuUtilization(DateTime? start = null, DateTime? end = null) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { //If no given start date, get date of most recent record if (start == null) { start = GetRecentDate(db); } var data = from facts in GetClientFacts(db, start, end) select new { Time = facts.Key, CpuUtilization = facts.Average(x => x.CpuUtilization) }; return Json( CreateSeriesData(data.ToList(), x => x.Time, x => x.CpuUtilization), JsonRequestBehavior.AllowGet); } } public JsonResult UsedCores(DateTime? start = null, DateTime? end = null) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { //If no given start date, get date of most recent record if (start == null) { start = GetRecentDate(db); } var data = from facts in GetClientFacts(db, start, end) select new { Time = facts.Key, UsedCores = facts.Sum(x => x.NumUsedCores), TotalCores = facts.Sum(x => x.NumTotalCores) }; return Json( CreateSeriesData(data.ToList(), x => x.Time, x => x.UsedCores, x => x.TotalCores), JsonRequestBehavior.AllowGet); } } public JsonResult UsedMemory(DateTime? start = null, DateTime? end = null) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { //If no given start date, get date of most recent record if (start == null) { start = GetRecentDate(db); } var data = from facts in GetClientFacts(db, start, end) select new { Time = facts.Key, UsedMemory = facts.Sum(x => x.UsedMemory), TotalMemory = facts.Sum(x => x.TotalMemory) }; // Return values in GB return Json( CreateSeriesData(data.ToList(), x => x.Time, x => x.UsedMemory / 1000, x => x.TotalMemory / 1000), JsonRequestBehavior.AllowGet); } } public JsonResult CurrentCpuUtilization(string state) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var currentCpuUtil = (from client in db.FactClientInfos join clients in db.DimClients on client.ClientId equals clients.Id join resource in db.Resources.OfType() on clients.ResourceId equals resource.ResourceId where clients.ExpirationTime == null && (state == "All") || (state == "Online") && (client.SlaveState == SlaveState.Idle || client.SlaveState == SlaveState.Calculating ) || (state == "Available") && (client.SlaveState == SlaveState.Idle) select new { client.ClientId, client.CpuUtilization, client.Time }) .OrderBy(c => c.Time).GroupBy(c => c.ClientId).ToList(); List result = new List(); result.Add(Math.Round(currentCpuUtil.Average(s => s.Last().CpuUtilization), 2)); return Json(result, JsonRequestBehavior.AllowGet); } } public JsonResult CurrentCores(string state) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var currentCores = (from client in db.FactClientInfos join clients in db.DimClients on client.ClientId equals clients.Id join resource in db.Resources.OfType() on clients.ResourceId equals resource.ResourceId where clients.ExpirationTime == null && (state == "All") || (state == "Online") && (client.SlaveState == SlaveState.Idle || client.SlaveState == SlaveState.Calculating) || (state == "Available") && (client.SlaveState == SlaveState.Idle) select new { client.ClientId, client.NumTotalCores, client.NumUsedCores, client.Time }) .OrderBy(c => c.Time).GroupBy(c => c.ClientId).ToList(); List result = new List(); result.Add(currentCores.Sum(c => c.Last().NumTotalCores)); result.Add(currentCores.Sum(s => s.Last().NumUsedCores)); return Json(result, JsonRequestBehavior.AllowGet); } } public JsonResult CurrentMemory(string state) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var currentMemory = (from client in db.FactClientInfos join clients in db.DimClients on client.ClientId equals clients.Id join resource in db.Resources.OfType() on clients.ResourceId equals resource.ResourceId where clients.ExpirationTime == null && (state == "All") || (state == "Online") && (client.SlaveState == SlaveState.Idle || client.SlaveState == SlaveState.Calculating) || (state == "Available") && (client.SlaveState == SlaveState.Idle) select new { client.ClientId, client.TotalMemory, client.UsedMemory, client.Time }) .OrderBy(c => c.Time).GroupBy(c => c.ClientId).ToList(); List result = new List(); result.Add(currentMemory.Sum(c => c.Last().TotalMemory)/1000); result.Add(currentMemory.Sum(s => s.Last().UsedMemory)/1000); return Json(result, JsonRequestBehavior.AllowGet); } } public JsonResult GetTasks(string userName, DateTime? start = null, DateTime? end = null, string jobId = null, string taskState = null) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { TaskState? state = GetTaskState(taskState); var data = (from tasks in db.FactTasks join jobs in db.DimJobs on tasks.JobId equals jobs.JobId where jobs.UserName == userName && (!start.HasValue || tasks.StartTime >= start) && (!end.HasValue || tasks.EndTime < end) && (string.IsNullOrEmpty(jobId) || tasks.JobId.ToString() == jobId) && (string.IsNullOrEmpty(taskState) || tasks.TaskState == state) select new { JobName = jobs.JobName, JobId = jobs.JobId, TaskId = tasks.TaskId, StartDate = tasks.StartTime }).OrderByDescending(s => s.StartDate).ToList(); //Was overflowing default MaxJsonLength //return Json(data, JsonRequestBehavior.AllowGet); return new JsonResult() { Data = data, JsonRequestBehavior = JsonRequestBehavior.AllowGet, MaxJsonLength = Int32.MaxValue }; } } public JsonResult TaskInfo(string taskId) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var data = (from tasks in db.FactTasks join jobs in db.DimJobs on tasks.JobId equals jobs.JobId where tasks.TaskId.ToString() == taskId select new { TotalWaiting = tasks.TotalWaitingTime, TotalTransfer = tasks.TotalTransferTime, TotalRuntime = tasks.TotalRuntime, StartDate = tasks.StartTime }).OrderByDescending(s => s.StartDate).ToList(); return Json(data, JsonRequestBehavior.AllowGet); } } public JsonResult GetSlaves(DateTime? start = null, DateTime? end = null, string userName = null, string slaveId = null) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var data = (from slaves in db.FactClientInfos join users in db.DimUsers on slaves.UserId equals users.UserId join clients in db.DimClients on slaves.ClientId equals clients.Id where (!start.HasValue || slaves.Time >= start) && (!end.HasValue || slaves.Time < end) && (string.IsNullOrEmpty(userName) || users.Name == userName) && (string.IsNullOrEmpty(slaveId) || slaves.ClientId.ToString() == slaveId) select new { ClientName = clients.Name, SlaveID = slaves.ClientId, }).GroupBy(s => s.SlaveID).ToList(); //Was overflowing default MaxJsonLength //return Json(data, JsonRequestBehavior.AllowGet); return new JsonResult() { Data = data, JsonRequestBehavior = JsonRequestBehavior.AllowGet, MaxJsonLength = Int32.MaxValue }; } } public JsonResult SlaveInfo(string slaveId, DateTime? start = null, DateTime? end = null, string userName = null) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var data = (from slaves in db.FactClientInfos join users in db.DimUsers on slaves.UserId equals users.UserId join clients in db.DimClients on slaves.ClientId equals clients.Id where slaves.ClientId.ToString() == slaveId && (!start.HasValue || slaves.Time >= start) && (!end.HasValue || slaves.Time < end) && (string.IsNullOrEmpty(userName) || users.Name == userName) select new { ClientName = clients.Name, SlaveID = slaves.ClientId, Time = slaves.Time, UsedCores = slaves.NumUsedCores, TotalCores = slaves.NumTotalCores, UsedMemory = slaves.UsedMemory, TotalMemory = slaves.TotalMemory, CPUUtilization = slaves.CpuUtilization }).OrderByDescending(s => s.Time).ToList(); return Json(data, JsonRequestBehavior.AllowGet); } } public JsonResult JobProgress(string jobId) { using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var data = (from tasks in db.FactTasks where tasks.JobId.ToString() == jobId select new { State = tasks.TaskState }).ToList(); Dictionary JobTasks = new Dictionary(); JobTasks.Add("Wait",0); JobTasks.Add("Transfer", 0); JobTasks.Add("Calculate", 0); JobTasks.Add("Finish", 0); JobTasks.Add("Error", 0); foreach(var record in data) { switch (record.State) { case TaskState.Waiting: JobTasks["Wait"] += 1; break; case TaskState.Transferring: JobTasks["Transfer"] += 1; break; case TaskState.Calculating: JobTasks["Calculate"] += 1; break; case TaskState.Finished: JobTasks["Finish"] += 1; break; case TaskState.Aborted: case TaskState.Failed: JobTasks["Error"] += 1; break; } } return Json(JobTasks, JsonRequestBehavior.AllowGet); } } public JsonResult UserTasks(string taskState) { TaskState? state = GetTaskState(taskState); List> numberTasksByUser = new List>(); using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) { var userTasks = (from tasks in db.FactTasks join jobs in db.DimJobs on tasks.JobId equals jobs.JobId where tasks.TaskState == state select new { UserID = jobs.UserId, UserName = jobs.UserName, State = tasks.TaskState }).GroupBy(j => j.UserID).ToList(); foreach (var user in userTasks) { numberTasksByUser.Add(new KeyValuePair(user.First().UserName, user.Count())); } return Json(numberTasksByUser, JsonRequestBehavior.AllowGet); } } private static TaskState? GetTaskState(string taskState) { TaskState? state; switch (taskState) { case "Aborted": state = TaskState.Aborted; break; case "Calculating": state = TaskState.Calculating; break; case "Failed": state = TaskState.Failed; break; case "Finished": state = TaskState.Finished; break; case "Offline": state = TaskState.Offline; break; case "Paused": state = TaskState.Paused; break; case "Transferring": state = TaskState.Transferring; break; case "Waiting": state = TaskState.Waiting; break; default : state = null; break; } return state; } private static IOrderedQueryable> GetClientFacts(HiveDataContext db, DateTime? start = null, DateTime? end = null) { start = start ?? DateTime.Now - DefaultDuration; end = end ?? DateTime.Now; return from ci in db.FactClientInfos where ci.Time >= start && ci.Time < end group ci by ci.Time into timeGroup orderby timeGroup.Key select timeGroup; } private static IEnumerable> CreateSeriesData(IEnumerable data, Func timeSelector, params Func[] seriesSelectors) { return seriesSelectors.Select(selector => data.Select(x => new[] { timeSelector(x).ToUniversalTime().ToUnixTimestamp(), selector(x) }) ); } private static DateTime GetRecentDate(HiveDataContext db) { var mostRecent = from dates in db.FactClientInfos group dates by dates.Time into startDate select startDate.OrderByDescending(t=>t.Time).FirstOrDefault(); return mostRecent.Max(t=>t.Time); } } public static class DateTimeExtensions { public static long ToUnixTimestamp(this DateTime dateTime) { var duration = dateTime - new DateTime(1970, 1, 1, 0, 0, 0); return (long)duration.TotalMilliseconds; } } }