Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataController.cs @ 12515

Last change on this file since 12515 was 12515, checked in by dglaser, 9 years ago

#2388: Merged trunk into HiveStatistics branch

File size: 9.2 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.Data.Linq;
25using System.Linq;
26using System.Web.Http;
27using HeuristicLab.Services.Hive;
28using HeuristicLab.Services.Hive.DataAccess;
29using HeuristicLab.Services.Hive.DataAccess.Interfaces;
30using DA = HeuristicLab.Services.Hive.DataAccess;
31using DT = HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer;
32
33namespace 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}
Note: See TracBrowser for help on using the repository browser.