Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveProjectManagement/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ClientController.cs @ 15671

Last change on this file since 15671 was 15671, checked in by jzenisek, 6 years ago

#2839

  • adapted computation of DimClient and FactClientInfo stats
  • adapted web app according to new stats computation
File size: 13.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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.Linq;
25using System.Web.Http;
26using HeuristicLab.Services.Hive;
27using HeuristicLab.Services.Hive.DataAccess;
28using HeuristicLab.Services.Hive.DataAccess.Interfaces;
29using DT = HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer;
30
31namespace HeuristicLab.Services.WebApp.Statistics.WebApi {
32
33  [Authorize]
34  public class ClientController : ApiController {
35    private IPersistenceManager PersistenceManager {
36      get { return ServiceLocator.Instance.PersistenceManager; }
37    }
38
39    public DT.ClientDetails GetClientDetails(Guid id) {
40      var pm = PersistenceManager;
41      var dimClientDao = pm.DimClientDao;
42      var factClientInfoDao = pm.FactClientInfoDao;
43      var factTaskDao = pm.FactTaskDao;
44      return pm.UseTransaction(() => {
45        var timeData = factClientInfoDao.GetByClientId(id)
46          .GroupBy(x => x.ClientId)
47          .Select(x => new {
48            TotalIdleTime = x.Sum(y => y.IdleTime),
49            TotalOfflineTime = x.Sum(y => y.OfflineTime),
50            TotalUnavailableTime = x.Sum(y => y.UnavailableTime)
51          }).FirstOrDefault();
52        var taskTimeData = factTaskDao.GetByClientId(id)
53          .GroupBy(x => x.LastClientId)
54          .Select(x => new {
55            TotalCalculatingTime = x.Sum(y => y.CalculatingTime),
56            TotalTransferringTime = x.Sum(y => y.TransferTime)
57          }).FirstOrDefault();
58        var startDate = factClientInfoDao.GetByClientId(id)
59          .Where(x => x.SlaveState == SlaveState.Offline)
60          .OrderByDescending(x => x.Time)
61          .Select(x => x.Time).FirstOrDefault();
62        long upTime = 0;
63        if (startDate == default(DateTime)) {
64          startDate = factClientInfoDao.GetByClientId(id)
65            .OrderByDescending(x => x.Time)
66            .Select(x => x.Time)
67            .FirstOrDefault();
68        }
69        if (startDate != default(DateTime)) {
70          upTime = (long)(DateTime.Now - startDate).TotalSeconds;
71        }
72        return (from client in dimClientDao.GetAll().Where(x => x.Id == id)
73                join info in factClientInfoDao.GetAll()
74                  on client.Id equals info.ClientId into clientInfoJoin
75                from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
76                let offline = (client.DateExpired != null || clientInfo.SlaveState == SlaveState.Offline)
77                let parent = client.ParentResourceId.HasValue ? dimClientDao.GetById(client.ParentResourceId.Value) : null
78                select new DT.ClientDetails {
79                  Id = client.Id,
80                  Name = client.Name,
81                  TotalCores = clientInfo.NumTotalCores,
82                  UsedCores = offline ? 0 : clientInfo.NumUsedCores,
83                  TotalMemory = clientInfo.TotalMemory,
84                  UsedMemory = offline ? 0 : clientInfo.UsedMemory,
85                  CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
86                  State = offline ? SlaveState.Offline.ToString() : clientInfo.SlaveState.ToString(),
87                  LastUpdate = clientInfo.Time,
88                  GroupId = client.ParentResourceId,
89                  GroupName = parent != null ? parent.Name : null,
90                  UpTime = offline ? 0 : upTime,
91                  TotalUnavailableTime = timeData != null ? timeData.TotalUnavailableTime : 0,
92                  TotalCalculatingTime = taskTimeData != null ? taskTimeData.TotalCalculatingTime : 0,
93                  TotalIdleTime = timeData != null ? timeData.TotalIdleTime : 0,
94                  TotalOfflineTime = timeData != null ? timeData.TotalOfflineTime : 0,
95                  TotalTransferringTime = taskTimeData != null ? taskTimeData.TotalTransferringTime : 0,
96                  TasksStates = factTaskDao.GetByClientId(id)
97                                  .GroupBy(x => x.TaskState)
98                                  .Select(x => new DT.TaskStateCount {
99                                    State = x.Key.ToString(),
100                                    Count = x.Count()
101                                  }).ToList(),
102                  Users = factTaskDao.GetAll()
103                            .Where(x => x.LastClientId == id)
104                            .Select(x => new DT.User {
105                              Id = x.DimJob.UserId,
106                              Name = x.DimJob.UserName
107                            })
108                            .Distinct()
109                            .ToList()
110                })
111                .FirstOrDefault();
112      });
113    }
114
115    public DT.ClientPage GetClients(int page, int size, bool expired = false) {
116      var pm = PersistenceManager;
117      var dimClientDao = pm.DimClientDao;
118      var factClientInfoDao = pm.FactClientInfoDao;
119      return pm.UseTransaction(() => {
120        var clients = expired ? dimClientDao.GetAllExpiredSlaves() : dimClientDao.GetAllOnlineSlaves();
121        var query = (from client in clients
122                     join info in factClientInfoDao.GetAll()
123                       on client.Id equals info.ClientId into clientInfoJoin
124                     from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
125                     let offline = (expired || clientInfo.SlaveState == SlaveState.Offline)
126                     let parent = client.ParentResourceId.HasValue ? dimClientDao.GetById(client.ParentResourceId.Value) : null
127                     select new DT.Client {
128                       Id = client.Id,
129                       Name = client.Name,
130                       TotalCores = clientInfo.NumTotalCores,
131                       UsedCores = offline ? 0 : clientInfo.NumUsedCores,
132                       TotalMemory = clientInfo.TotalMemory,
133                       UsedMemory = offline ? 0 : clientInfo.UsedMemory,
134                       CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
135                       State = offline ? SlaveState.Offline.ToString() : clientInfo.SlaveState.ToString(),
136                       GroupId = client.ParentResourceId,
137                       GroupName = parent != null ? parent.Name : null,
138                       IsAllowedToCalculate = clientInfo.IsAllowedToCalculate
139                     });
140        return new DT.ClientPage {
141          TotalClients = query.Count(),
142          Clients = query.Skip((page - 1) * size)
143            .Take(size)
144            .ToList()
145        };
146      });
147    }
148
149    public IEnumerable<DT.ClientStatus> GetClientHistory(Guid id, DateTime start, DateTime end) {
150      TimeSpan ts = end - start;
151      int increment = 1;
152      double totalMinutes = ts.TotalMinutes;
153      while (totalMinutes > 5761) {
154        totalMinutes -= 5761;
155        increment += 5;
156      }
157      var pm = PersistenceManager;
158      var factClientInfo = pm.FactClientInfoDao;
159      var clientInfos = factClientInfo.GetByClientId(id)
160        .Where(x => x.Time >= start && x.Time <= end)
161        .OrderBy(x => x.Time)
162        .ToList();
163      var clientStatus = new DT.ClientStatus {
164        CpuUtilization = 0,
165        TotalCores = 0,
166        UsedCores = 0,
167        TotalMemory = 0,
168        UsedMemory = 0
169      };
170      int i = 1;
171      foreach (var clientInfo in clientInfos) {
172        clientStatus.CpuUtilization += clientInfo.CpuUtilization;
173        clientStatus.TotalCores += clientInfo.NumTotalCores;
174        clientStatus.UsedCores += clientInfo.NumUsedCores;
175        clientStatus.TotalMemory += clientInfo.TotalMemory;
176        clientStatus.UsedMemory += clientInfo.UsedMemory;
177        if (i >= increment) {
178          clientStatus.Timestamp = JavascriptUtils.ToTimestamp(clientInfo.Time);
179          clientStatus.CpuUtilization /= i;
180          clientStatus.TotalCores /= i;
181          clientStatus.UsedCores /= i;
182          clientStatus.TotalMemory /= i;
183          clientStatus.UsedMemory /= i;
184          yield return clientStatus;
185          clientStatus = new DT.ClientStatus {
186            CpuUtilization = 0,
187            TotalCores = 0,
188            UsedCores = 0,
189            TotalMemory = 0,
190            UsedMemory = 0
191          };
192          i = 1;
193        } else {
194          ++i;
195        }
196      }
197    }
198
199    public DT.ClientPage GetClientsByGroupId(Guid id, int page, int size, bool expired = false) {
200      var pm = PersistenceManager;
201      var dimClientDao = pm.DimClientDao;
202      var factClientInfoDao = pm.FactClientInfoDao;
203      return pm.UseTransaction(() => {
204        var clients = expired ? dimClientDao.GetAllExpiredClients() : dimClientDao.GetAllOnlineClients();
205        clients = clients.Where(x => x.ParentResourceId == id);
206        var query = (from client in clients
207                     join info in factClientInfoDao.GetAll()
208                       on client.Id equals info.ClientId into clientInfoJoin
209                     from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
210                     let offline = (expired || clientInfo.SlaveState == SlaveState.Offline)
211                     let parent = client.ParentResourceId.HasValue ? dimClientDao.GetById(client.ParentResourceId.Value) : null
212                     select new DT.Client {
213                       Id = client.Id,
214                       Name = client.Name,
215                       TotalCores = clientInfo.NumTotalCores,
216                       UsedCores = offline ? 0 : clientInfo.NumUsedCores,
217                       TotalMemory = clientInfo.TotalMemory,
218                       UsedMemory = offline ? 0 : clientInfo.UsedMemory,
219                       CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
220                       State = offline ? SlaveState.Offline.ToString() : clientInfo.SlaveState.ToString(),
221                       GroupId = client.ParentResourceId,
222                       GroupName = parent != null ? parent.Name : null,
223                       IsAllowedToCalculate = clientInfo.IsAllowedToCalculate
224                     });
225        return new DT.ClientPage {
226          TotalClients = query.Count(),
227          Clients = query.Skip((page - 1) * size)
228            .Take(size)
229            .ToList()
230        };
231      });
232    }
233
234    public IEnumerable<DT.ClientStatus> GetClientHistoryByGroupId(Guid id, DateTime start, DateTime end) {
235      TimeSpan ts = end - start;
236      int increment = 1;
237      double totalMinutes = ts.TotalMinutes;
238      while (totalMinutes > 5761) {
239        totalMinutes -= 5761;
240        increment += 5;
241      }
242      var pm = PersistenceManager;
243      var factClientInfo = pm.FactClientInfoDao;
244      var dimClientDao = pm.DimClientDao;
245      var clientInfos = factClientInfo.GetAll()
246        .Where(x => x.Time >= start && x.Time <= end)
247        .OrderBy(x => x.Time)
248        .Join(dimClientDao.GetAll(),
249          fact => fact.ClientId,
250          client => client.Id,
251          (fact, client) => new {
252            client.ParentResourceId,
253            fact.Time,
254            fact.CpuUtilization,
255            fact.NumTotalCores,
256            fact.NumUsedCores,
257            fact.TotalMemory,
258            fact.UsedMemory
259          })
260        .Where(x => x.ParentResourceId == id)
261        .ToList();
262      var clientStatus = new DT.ClientStatus {
263        CpuUtilization = 0,
264        TotalCores = 0,
265        UsedCores = 0,
266        TotalMemory = 0,
267        UsedMemory = 0
268      };
269      int i = 1;
270      foreach (var clientInfo in clientInfos) {
271        clientStatus.CpuUtilization += clientInfo.CpuUtilization;
272        clientStatus.TotalCores += clientInfo.NumTotalCores;
273        clientStatus.UsedCores += clientInfo.NumUsedCores;
274        clientStatus.TotalMemory += clientInfo.TotalMemory;
275        clientStatus.UsedMemory += clientInfo.UsedMemory;
276        if (i >= increment) {
277          clientStatus.Timestamp = JavascriptUtils.ToTimestamp(clientInfo.Time);
278          clientStatus.CpuUtilization /= i;
279          clientStatus.TotalCores /= i;
280          clientStatus.UsedCores /= i;
281          clientStatus.TotalMemory /= i;
282          clientStatus.UsedMemory /= i;
283          yield return clientStatus;
284          clientStatus = new DT.ClientStatus {
285            CpuUtilization = 0,
286            TotalCores = 0,
287            UsedCores = 0,
288            TotalMemory = 0,
289            UsedMemory = 0
290          };
291          i = 1;
292        } else {
293          ++i;
294        }
295      }
296    }
297  }
298}
Note: See TracBrowser for help on using the repository browser.