Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataController.cs @ 12445

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

#2394:
Changed Web.config compilation from debug to release to force script bundling.
Changed history loading type from lazy to eager loading to increase performance.
Fixed "getCoreStatus" typo in statusCtrl.js

File size: 8.5 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 DAL = HeuristicLab.Services.Hive.DataAccess;
30using DTO = HeuristicLab.Services.WebApp.Status.WebApi.DataTransfer;
31
32namespace HeuristicLab.Services.WebApp.Status.WebApi {
33  public class DataController : ApiController {
34
35    // start temporary quickfix
36    private const string SQL_USER_TASK_STATUS =
37      @"WITH UserTasks AS (
38          SELECT Job.OwnerUserId AS UserId, TaskState, COUNT(Task.TaskId) AS Count
39          FROM Task, Job
40          WHERE Task.JobId = Job.JobId AND TaskState IN ('Calculating', 'Waiting')
41          GROUP BY Job.OwnerUserId, TaskState
42        )
43        SELECT
44          DISTINCT UserId,
45          ISNULL((SELECT Count FROM UserTasks WHERE TaskState = 'Calculating' AND UserId = ut.UserId), 0) AS CalculatingTasks,
46          ISNULL((SELECT Count FROM UserTasks WHERE TaskState = 'Waiting' AND UserId = ut.UserId), 0) AS WaitingTasks
47        FROM UserTasks ut;";
48
49    private class UserTaskStatus {
50      public Guid UserId { get; set; }
51      public int CalculatingTasks { get; set; }
52      public int WaitingTasks { get; set; }
53    }
54
55    public IEnumerable<DTO.TaskStatus> GetTaskStatus(HiveDataContext db) {
56      var query = db.ExecuteQuery<UserTaskStatus>(SQL_USER_TASK_STATUS).ToList();
57      return query.Select(uts => new DTO.TaskStatus {
58        User = new DTO.User {
59          Id = uts.UserId.ToString(),
60          Name = ServiceLocator.Instance.UserManager.GetUserById(uts.UserId).UserName
61        },
62        CalculatingTasks = uts.CalculatingTasks,
63        WaitingTasks = uts.WaitingTasks
64      }).OrderBy(x => x.User.Name);
65    }
66    // end temporary quickfix
67
68    public DTO.Status GetStatus() {
69      using (var db = new HiveDataContext()) {
70        var onlineSlaves = (from slave in db.Resources.OfType<DAL.Slave>()
71                            where slave.SlaveState == SlaveState.Calculating || slave.SlaveState == SlaveState.Idle
72                            select slave).ToList();
73        var activeSlaves = onlineSlaves.Where(s => s.IsAllowedToCalculate).ToList();
74        var calculatingSlaves = activeSlaves.Where(s => s.SlaveState == SlaveState.Calculating).ToList();
75        int calculatingMemory = calculatingSlaves.Any() ? (int)calculatingSlaves.Sum(s => s.Memory) / 1024 : 0;
76        int freeCalculatingMemory = calculatingSlaves.Any() ? (int)calculatingSlaves.Sum(s => s.FreeMemory) / 1024 : 0;
77
78        return new DTO.Status {
79          CoreStatus = new DTO.CoreStatus {
80            TotalCores = onlineSlaves.Sum(s => s.Cores ?? 0),
81            FreeCores = onlineSlaves.Sum(s => s.FreeCores ?? 0), // temporary for old chart data
82            ActiveCores = activeSlaves.Sum(s => s.Cores ?? 0),
83            CalculatingCores = calculatingSlaves.Sum(s => s.Cores ?? 0)
84          },
85          CpuUtilizationStatus = new DTO.CpuUtilizationStatus {
86            TotalCpuUtilization = onlineSlaves.Any()
87                                  ? Math.Round(onlineSlaves.Average(s => s.CpuUtilization), 2)
88                                  : 0.0,
89            ActiveCpuUtilization = activeSlaves.Any()
90                                   ? Math.Round(activeSlaves.Average(s => s.CpuUtilization), 2)
91                                   : 0.0,
92            CalculatingCpuUtilization = calculatingSlaves.Any()
93                                        ? Math.Round(calculatingSlaves.Average(s => s.CpuUtilization), 2)
94                                        : 0.0
95          },
96          MemoryStatus = new DTO.MemoryStatus {
97            TotalMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.Memory) / 1024 : 0,
98            FreeMemory = onlineSlaves.Any() ? (int)onlineSlaves.Sum(s => s.FreeMemory) / 1024 : 0,
99            ActiveMemory = activeSlaves.Any() ? (int)activeSlaves.Sum(s => s.Memory) / 1024 : 0,
100            UsedMemory = calculatingMemory - freeCalculatingMemory
101          },
102          TasksStatus = GetTaskStatus(db),
103          SlavesStatus = onlineSlaves.Select(x => new DTO.SlaveStatus {
104            Slave = new DTO.Slave {
105              Id = x.ResourceId.ToString(),
106              Name = x.Name
107            },
108            CpuUtilization = x.CpuUtilization,
109            Cores = x.Cores ?? 0,
110            FreeCores = x.FreeCores ?? 0,
111            Memory = (x.Memory ?? 0) / 1024,
112            FreeMemory = (x.FreeMemory ?? 0) / 1024,
113            IsAllowedToCalculate = x.IsAllowedToCalculate,
114            State = x.SlaveState.ToString()
115          }).OrderBy(x => x.Slave.Name),
116          Timestamp = JavascriptUtils.ToTimestamp(DateTime.Now)
117        };
118      }
119    }
120
121    public IEnumerable<DTO.Status> GetStatusHistory(DateTime start, DateTime end) {
122      TimeSpan ts = end - start;
123      int increment = 1;
124      double totalMinutes = ts.TotalMinutes;
125      while (totalMinutes > 5761) {
126        totalMinutes -= 5761;
127        increment += 5;
128      }
129      using (var db = new HiveDataContext()) {
130        DataLoadOptions loadOptions = new DataLoadOptions();
131        loadOptions.LoadWith<Statistics>(o => o.SlaveStatistics);
132        db.LoadOptions = loadOptions;
133        db.DeferredLoadingEnabled = false;
134        var statistics = db.Statistics.Where(s => s.Timestamp >= start && s.Timestamp <= end)
135                                      .OrderBy(s => s.Timestamp)
136                                      .ToList();
137        var status = new DTO.Status {
138          CoreStatus = new DTO.CoreStatus(),
139          CpuUtilizationStatus = new DTO.CpuUtilizationStatus(),
140          MemoryStatus = new DTO.MemoryStatus()
141        };
142        int freeCores = 0;
143        int freeMemory = 0;
144        int i = 1;
145        foreach (var statistic in statistics) {
146          status.CoreStatus.TotalCores += statistic.SlaveStatistics.Sum(x => x.Cores);
147          freeCores += statistic.SlaveStatistics.Sum(x => x.FreeCores);
148          status.CpuUtilizationStatus.TotalCpuUtilization += statistic.SlaveStatistics.Any()
149                                                             ? statistic.SlaveStatistics.Average(x => x.CpuUtilization)
150                                                             : 0.0;
151          status.MemoryStatus.TotalMemory += statistic.SlaveStatistics.Sum(x => x.Memory) / 1024;
152          freeMemory += statistic.SlaveStatistics.Sum(x => x.FreeMemory) / 1024;
153          if (i >= increment) {
154            status.Timestamp = JavascriptUtils.ToTimestamp(statistic.Timestamp);
155            status.CoreStatus.TotalCores /= i;
156            freeCores /= i;
157            status.CpuUtilizationStatus.TotalCpuUtilization /= i;
158            status.MemoryStatus.TotalMemory /= i;
159            freeMemory /= i;
160            status.CoreStatus.ActiveCores = status.CoreStatus.TotalCores;
161            status.MemoryStatus.ActiveMemory = status.MemoryStatus.TotalMemory;
162            status.CpuUtilizationStatus.ActiveCpuUtilization = status.CpuUtilizationStatus.TotalCpuUtilization;
163            status.CpuUtilizationStatus.CalculatingCpuUtilization = status.CpuUtilizationStatus.CalculatingCpuUtilization;
164            status.CoreStatus.CalculatingCores = status.CoreStatus.TotalCores - freeCores;
165            status.MemoryStatus.UsedMemory = status.MemoryStatus.TotalMemory - freeMemory;
166            yield return status;
167            status = new DTO.Status {
168              CoreStatus = new DTO.CoreStatus(),
169              CpuUtilizationStatus = new DTO.CpuUtilizationStatus(),
170              MemoryStatus = new DTO.MemoryStatus()
171            };
172            freeCores = 0;
173            freeMemory = 0;
174            i = 1;
175          } else {
176            i++;
177          }
178        }
179      }
180    }
181  }
182}
Note: See TracBrowser for help on using the repository browser.