1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022015 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 


22  using System;


23  using System.Collections.Generic;


24  using System.Data.Linq;


25  using System.Linq;


26  using System.Web.Http;


27  using HeuristicLab.Services.Hive;


28  using HeuristicLab.Services.Hive.DataAccess;


29  using HeuristicLab.Services.Hive.DataAccess.Interfaces;


30  using DA = HeuristicLab.Services.Hive.DataAccess;


31  using DT = HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer;


32 


33  namespace HeuristicLab.Services.WebApp.Status.WebApi {


34  public class DataController : ApiController {


35  private IPersistenceManager PersistenceManager {


36  get { return ServiceLocator.Instance.PersistenceManager; }


37  }


38 


39  // start temporary quickfix


40  private const string SQL_USER_TASK_STATUS =


41  @"WITH UserTasks AS (


42  SELECT Job.OwnerUserId AS UserId, TaskState, COUNT(Task.TaskId) AS Count


43  FROM Task, Job


44  WHERE Task.JobId = Job.JobId AND TaskState IN ('Calculating', 'Waiting')


45  GROUP BY Job.OwnerUserId, TaskState


46  )


47  SELECT


48  DISTINCT UserId,


49  ISNULL((SELECT Count FROM UserTasks WHERE TaskState = 'Calculating' AND UserId = ut.UserId), 0) AS CalculatingTasks,


50  ISNULL((SELECT Count FROM UserTasks WHERE TaskState = 'Waiting' AND UserId = ut.UserId), 0) AS WaitingTasks


51  FROM UserTasks ut;";


52 


53  private class UserTaskStatus {


54  public Guid UserId { get; set; }


55  public int CalculatingTasks { get; set; }


56  public int WaitingTasks { get; set; }


57  }


58 


59  public IEnumerable<DT.TaskStatus> GetTaskStatus(HiveDataContext db) {


60  var query = db.ExecuteQuery<UserTaskStatus>(SQL_USER_TASK_STATUS).ToList();


61  return query.Select(uts => new DT.TaskStatus {


62  User = new DT.User {


63  Id = uts.UserId.ToString(),


64  Name = ServiceLocator.Instance.UserManager.GetUserById(uts.UserId).UserName


65  },


66  CalculatingTasks = uts.CalculatingTasks,


67  WaitingTasks = uts.WaitingTasks


68  }).OrderBy(x => x.User.Name);


69  }


70  // end temporary quickfix


71 


72  public DT.Status GetStatus() {


73  DT.TimeStatus timeStatus = null;


74  using (var pm = PersistenceManager) {


75 


76  // TODO:


77  // new DT.TimeStatus {


78  // AvgCalculatingTime = 0,


79  // AvgWaitingTime = 0,


80  // MaxCalculatingTime = 0,


81  // MinCalculatingTime = 0,


82  // TotalCpuTime = 0,


83  // BeginDate = DateTime.Now


84  //}


85  }


86 


87  using (var db = new HiveDataContext()) {


88  var onlineSlaves = (from slave in db.Resources.OfType<DA.Slave>()


89  where slave.SlaveState == SlaveState.Calculating  slave.SlaveState == SlaveState.Idle


90  select slave).ToList();


91  var activeSlaves = onlineSlaves.Where(s => s.IsAllowedToCalculate).ToList();


92  var calculatingSlaves = activeSlaves.Where(s => s.SlaveState == SlaveState.Calculating).ToList();


93  int calculatingMemory = calculatingSlaves.Any() ? (int)calculatingSlaves.Sum(s => s.Memory) / 1024 : 0;


94  int freeCalculatingMemory = calculatingSlaves.Any() ? (int)calculatingSlaves.Sum(s => s.FreeMemory) / 1024 : 0;


95 


96  return new DT.Status {


97  CoreStatus = new DT.CoreStatus {


98  TotalCores = onlineSlaves.Sum(s => s.Cores ?? 0),


99  FreeCores = onlineSlaves.Sum(s => s.FreeCores ?? 0), // temporary for old chart data


100  ActiveCores = activeSlaves.Sum(s => s.Cores ?? 0),


101  CalculatingCores = calculatingSlaves.Sum(s => s.Cores ?? 0)  calculatingSlaves.Sum(s => s.FreeCores ?? 0)


102  },


103  CpuUtilizationStatus = new DT.CpuUtilizationStatus {


104  TotalCpuUtilization = onlineSlaves.Any()


105  ? Math.Round(onlineSlaves.Average(s => s.CpuUtilization), 2)


106  : 0.0,


107  ActiveCpuUtilization = activeSlaves.Any()


108  ? Math.Round(activeSlaves.Average(s => s.CpuUtilization), 2)


109  : 0.0,


110  CalculatingCpuUtilization = calculatingSlaves.Any()


111  ? Math.Round(calculatingSlaves.Average(s => s.CpuUtilization), 2)


112  : 0.0


113  },


114  MemoryStatus = new DT.MemoryStatus {


115  TotalMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.Memory) / 1024 : 0,


116  FreeMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.FreeMemory) / 1024 : 0,


117  ActiveMemory = activeSlaves.Any() ? (int)activeSlaves.Sum(s => s.Memory) / 1024 : 0,


118  UsedMemory = calculatingMemory  freeCalculatingMemory


119  },


120  TimeStatus = timeStatus,


121  TasksStatus = GetTaskStatus(db),


122  SlavesStatus = onlineSlaves.Select(x => new DT.SlaveStatus {


123  Slave = new DT.Slave {


124  Id = x.ResourceId.ToString(),


125  Name = x.Name


126  },


127  CpuUtilization = x.CpuUtilization,


128  Cores = x.Cores ?? 0,


129  FreeCores = x.FreeCores ?? 0,


130  Memory = (x.Memory ?? 0) / 1024,


131  FreeMemory = (x.FreeMemory ?? 0) / 1024,


132  IsAllowedToCalculate = x.IsAllowedToCalculate,


133  State = x.SlaveState.ToString()


134  }).OrderBy(x => x.Slave.Name),


135  Timestamp = JavascriptUtils.ToTimestamp(DateTime.Now)


136  };


137  }


138  }


139 


140  public IEnumerable<DT.Status> GetStatusHistory(DateTime start, DateTime end) {


141  TimeSpan ts = end  start;


142  int increment = 1;


143  double totalMinutes = ts.TotalMinutes;


144  while (totalMinutes > 5761) {


145  totalMinutes = 5761;


146  increment += 5;


147  }


148  using (var db = new HiveDataContext()) {


149  DataLoadOptions loadOptions = new DataLoadOptions();


150  loadOptions.LoadWith<Statistics>(o => o.SlaveStatistics);


151  db.LoadOptions = loadOptions;


152  db.DeferredLoadingEnabled = false;


153  var statistics = db.Statistics.Where(s => s.Timestamp >= start && s.Timestamp <= end)


154  .OrderBy(s => s.Timestamp)


155  .ToList();


156  var status = new DT.Status {


157  CoreStatus = new DT.CoreStatus(),


158  CpuUtilizationStatus = new DT.CpuUtilizationStatus(),


159  MemoryStatus = new DT.MemoryStatus()


160  };


161  int freeCores = 0;


162  int freeMemory = 0;


163  int i = 1;


164  foreach (var statistic in statistics) {


165  status.CoreStatus.TotalCores += statistic.SlaveStatistics.Sum(x => x.Cores);


166  freeCores += statistic.SlaveStatistics.Sum(x => x.FreeCores);


167  status.CpuUtilizationStatus.TotalCpuUtilization += statistic.SlaveStatistics.Any()


168  ? statistic.SlaveStatistics.Average(x => x.CpuUtilization)


169  : 0.0;


170  status.MemoryStatus.TotalMemory += statistic.SlaveStatistics.Sum(x => x.Memory) / 1024;


171  freeMemory += statistic.SlaveStatistics.Sum(x => x.FreeMemory) / 1024;


172  if (i >= increment) {


173  status.Timestamp = JavascriptUtils.ToTimestamp(statistic.Timestamp);


174  status.CoreStatus.TotalCores /= i;


175  freeCores /= i;


176  status.CpuUtilizationStatus.TotalCpuUtilization /= i;


177  status.MemoryStatus.TotalMemory /= i;


178  freeMemory /= i;


179  status.CoreStatus.ActiveCores = status.CoreStatus.TotalCores;


180  status.MemoryStatus.ActiveMemory = status.MemoryStatus.TotalMemory;


181  status.CpuUtilizationStatus.ActiveCpuUtilization = status.CpuUtilizationStatus.TotalCpuUtilization;


182  status.CpuUtilizationStatus.CalculatingCpuUtilization = status.CpuUtilizationStatus.CalculatingCpuUtilization;


183  status.CoreStatus.CalculatingCores = status.CoreStatus.TotalCores  freeCores;


184  status.MemoryStatus.UsedMemory = status.MemoryStatus.TotalMemory  freeMemory;


185  yield return status;


186  status = new DT.Status {


187  CoreStatus = new DT.CoreStatus(),


188  CpuUtilizationStatus = new DT.CpuUtilizationStatus(),


189  MemoryStatus = new DT.MemoryStatus()


190  };


191  freeCores = 0;


192  freeMemory = 0;


193  i = 1;


194  } else {


195  i++;


196  }


197  }


198  }


199  }


200  }


201  } 
