Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2839_HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs @ 17932

Last change on this file since 17932 was 16057, checked in by jkarder, 6 years ago

#2839:

File size: 25.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 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 HeuristicLab.Services.Access.DataAccess;
27using HeuristicLab.Services.Hive.DataAccess;
28using HeuristicLab.Services.Hive.DataAccess.Manager;
29
30namespace HeuristicLab.Services.Hive {
31  public class HiveStatisticsGenerator : IStatisticsGenerator {
32
33    private const string UnknownUserName = "Unknown";
34    private static readonly TimeSpan SmallestTimeSpan = new TimeSpan(0, 5, 0);
35    private static readonly TaskState[] CompletedStates = { TaskState.Finished, TaskState.Aborted, TaskState.Failed };
36
37    public void GenerateStatistics() {
38      using (var pm = new PersistenceManager()) {
39
40        pm.UseTransaction(() => {
41          UpdateDimProjectTable(pm);
42          pm.SubmitChanges();
43        });
44
45        pm.UseTransaction(() => {
46          UpdateDimUserTable(pm);
47         
48          UpdateDimJobTable(pm);
49          UpdateDimClientsTable(pm);
50          pm.SubmitChanges();
51        });
52
53        DimTime time = null;
54        pm.UseTransaction(() => {
55          time = UpdateDimTimeTable(pm);
56          pm.SubmitChanges();
57        });
58
59        if (time != null) {
60          pm.UseTransaction(() => {
61            UpdateFactClientInfoTable(time, pm);
62            pm.SubmitChanges();
63            UpdateFactProjectInfoTable(time, pm);
64            pm.SubmitChanges();
65          });
66
67          pm.UseTransaction(() => {
68            UpdateFactTaskTable(pm);
69            try {
70              pm.SubmitChanges();
71              UpdateExistingDimJobs(pm);
72              pm.SubmitChanges();
73            }
74            catch (DuplicateKeyException e) {
75              var logger = LogFactory.GetLogger(typeof(HiveStatisticsGenerator).Namespace);
76              logger.Log(string.Format(
77                @"Propable change from summertime to wintertime, resulting in overlapping times.
78                          On wintertime to summertime change, slave timeouts and a fact gap will occur.
79                          Exception Details: {0}", e));
80            }
81          });
82        }
83
84        pm.UseTransaction(() => {
85          FlagJobsForDeletion(pm);
86          pm.SubmitChanges();
87        });
88      }
89    }
90
91    private DimTime UpdateDimTimeTable(PersistenceManager pm) {
92      var dimTimeDao = pm.DimTimeDao;
93      var now = DateTime.Now;
94      var timeEntry = new DimTime {
95        Time = now,
96        Minute = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0),
97        Hour = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0),
98        Day = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0),
99        Month = new DateTime(now.Year, now.Month, 1, 0, 0, 0),
100        Year = new DateTime(now.Year, 1, 1, 0, 0, 0)
101      };
102      return dimTimeDao.Save(timeEntry);
103    }
104
105    private void UpdateDimUserTable(PersistenceManager pm) {
106      var dimUserDao = pm.DimUserDao;
107      var resourceDao = pm.ResourceDao;
108      var jobDao = pm.JobDao;
109      var existingUserIds = dimUserDao.GetAll().Select(x => x.UserId);
110      var vaildResourceOwnerIds = resourceDao.GetResourcesWithValidOwner().Select(x => x.OwnerUserId.Value);
111      var jobOwnerIds = jobDao.GetAll().Select(x => x.OwnerUserId);
112      var newUserIds = vaildResourceOwnerIds
113        .Union(jobOwnerIds)
114        .Where(id => !existingUserIds.Contains(id))
115        .ToList();
116      dimUserDao.Save(newUserIds.Select(x => new DimUser {
117        UserId = x,
118        Name = GetUserName(x)
119      }));
120    }
121
122    // add new projects
123    // delete expired projects
124    // update information of existing projects
125    private void UpdateDimProjectTable(PersistenceManager pm) {
126      var projectDao = pm.ProjectDao;
127      var dimProjectDao = pm.DimProjectDao;
128
129      var projects = projectDao.GetAll().ToList();
130      var dimProjects = dimProjectDao.GetAllOnlineProjects().ToList();
131
132      var onlineProjects = dimProjects.Where(x => projects.Select(y => y.ProjectId).Contains(x.ProjectId));
133      var addedProjects = projects.Where(x => !dimProjects.Select(y => y.ProjectId).Contains(x.ProjectId));
134      var removedProjects = dimProjects.Where(x => !projects.Select(y => y.ProjectId).Contains(x.ProjectId));
135
136      // set expiration time of removed projects
137      foreach (var p in removedProjects) {
138        p.DateExpired = DateTime.Now;
139      }
140
141      // add new projects
142      dimProjectDao.Save(addedProjects.Select(x => new DimProject {
143        ProjectId = x.ProjectId,
144        ParentProjectId = x.ParentProjectId,
145        Name = x.Name,
146        Description = x.Description,
147        OwnerUserId = x.OwnerUserId,
148        StartDate = x.StartDate,
149        EndDate = x.EndDate,
150        DateCreated = x.DateCreated,
151        DateExpired = null
152      }));
153
154      // expire project if its parent has changed and create a new entry
155      // otherwise perform "normal" update
156      foreach (var dimP in onlineProjects) {
157        var p = projects.Where(x => x.ProjectId == dimP.ProjectId).SingleOrDefault();
158        if (p != null) {
159          if (dimP.ParentProjectId == null ? p.ParentProjectId != null : dimP.ParentProjectId != p.ParentProjectId) { // or: (!object.Equals(dimP.ParentProjectId, p.ParentProjectId))
160            dimP.DateExpired = DateTime.Now;
161            dimProjectDao.Save(new DimProject {
162              ProjectId = p.ProjectId,
163              ParentProjectId = p.ParentProjectId,
164              Name = p.Name,
165              Description = p.Description,
166              OwnerUserId = p.OwnerUserId,
167              StartDate = p.StartDate,
168              EndDate = p.EndDate,
169              DateCreated = p.DateCreated,
170              DateExpired = null
171            });
172          } else {
173            dimP.Name = p.Name;
174            dimP.Description = p.Description;
175            dimP.OwnerUserId = p.OwnerUserId;
176            dimP.StartDate = p.StartDate;
177            dimP.EndDate = p.EndDate;
178          }
179        }
180      }
181    }
182
183    private void UpdateDimJobTable(PersistenceManager pm) {
184      var dimProjectDao = pm.DimProjectDao;
185      var dimJobDao = pm.DimJobDao;
186      var jobDao = pm.JobDao;
187      var taskDao = pm.TaskDao;
188      var dimJobIds = dimJobDao.GetAll().Select(x => x.JobId);
189      var newJobs = jobDao.GetAll()
190        .Where(x => !dimJobIds.Contains(x.JobId))
191        .Select(x => new {
192          JobId = x.JobId,
193          UserId = x.OwnerUserId,
194          JobName = x.Name ?? string.Empty,
195          DateCreated = x.DateCreated,
196          ProjectId = dimProjectDao.GetLastValidIdByProjectId(x.ProjectId),
197          TotalTasks = taskDao.GetAll().Count(y => y.JobId == x.JobId)
198        })
199        .ToList();
200      dimJobDao.Save(newJobs.Select(x => new DimJob {
201        JobId = x.JobId,
202        JobName = x.JobName,
203        UserId = x.UserId,
204        UserName = GetUserName(x.UserId),
205        DateCreated = x.DateCreated,
206        ProjectId = x.ProjectId,
207        TotalTasks = x.TotalTasks,
208        CompletedTasks = 0,
209        DateCompleted = null
210      }));
211    }
212
213    private void UpdateExistingDimJobs(PersistenceManager pm) {
214      var dimProjectDao = pm.DimProjectDao;
215      var jobDao = pm.JobDao;
216      var dimJobDao = pm.DimJobDao;
217      var factTaskDao = pm.FactTaskDao;
218      foreach (var dimJob in dimJobDao.GetNotCompletedJobs()) {
219        var taskStates = factTaskDao.GetByJobId(dimJob.JobId)
220            .GroupBy(x => x.TaskState)
221            .Select(x => new {
222              State = x.Key,
223              Count = x.Count()
224            }).ToList();
225        int totalTasks = 0, completedTasks = 0;
226        foreach (var state in taskStates) {
227          totalTasks += state.Count;
228          if (CompletedStates.Contains(state.State)) {
229            completedTasks += state.Count;
230          }
231        }
232        var job = jobDao.GetById(dimJob.JobId);
233        if (totalTasks == completedTasks) {
234          var completeDate = factTaskDao.GetLastCompletedTaskFromJob(dimJob.JobId);
235          if (completeDate == null) {
236            if (job == null) {
237              completeDate = DateTime.Now;
238            }
239          }
240          dimJob.DateCompleted = completeDate;
241        }
242        if(job != null) {
243          dimJob.JobName = job.Name;
244          dimJob.ProjectId = dimProjectDao.GetLastValidIdByProjectId(job.ProjectId);
245        }
246
247        dimJob.TotalTasks = totalTasks;
248        dimJob.CompletedTasks = completedTasks;
249      }
250    }
251
252    private void FlagJobsForDeletion(PersistenceManager pm) {
253      var jobDao = pm.JobDao;
254      var jobs = jobDao.GetJobsReadyForDeletion();
255      foreach(var job in jobs) {
256        job.State = JobState.DeletionPending;
257      }
258    }
259
260    private void UpdateDimClientsTable(PersistenceManager pm) {
261      var dimClientDao = pm.DimClientDao;
262      var resourceDao = pm.ResourceDao;
263
264      var resources = resourceDao.GetAll().ToList();
265      var dimClients = dimClientDao.GetAllOnlineClients().ToList();
266
267      var onlineClients = dimClients.Where(x => resources.Select(y => y.ResourceId).Contains(x.ResourceId));
268      var addedResources = resources.Where(x => !dimClients.Select(y => y.ResourceId).Contains(x.ResourceId));
269      var removedResources = dimClients.Where(x => !resources.Select(y => y.ResourceId).Contains(x.ResourceId));
270
271      // set expiration time of removed resources
272      foreach(var r in removedResources) {
273        r.DateExpired = DateTime.Now;
274      }
275
276      // add new resources
277      dimClientDao.Save(addedResources.Select(x => new DimClient {
278        ResourceId = x.ResourceId,
279        ParentResourceId = x.ParentResourceId,
280        Name = x.Name,
281        ResourceType = x.ResourceType,
282        DateCreated = DateTime.Now,
283        DateExpired = null
284      }));
285
286      // expire client if its parent has changed and create a new entry
287      // otherwise perform "normal" update
288      foreach(var dimc in onlineClients) {
289        var r = resources.Where(x => x.ResourceId == dimc.ResourceId).SingleOrDefault();
290        if(r != null) {
291          if(dimc.ParentResourceId == null ? r.ParentResourceId != null : dimc.ParentResourceId != r.ParentResourceId) {
292            var now = DateTime.Now;
293            dimc.DateExpired = now;
294            dimClientDao.Save(new DimClient {
295              ResourceId = r.ResourceId,
296              ParentResourceId = r.ParentResourceId,
297              Name = r.Name,
298              ResourceType = r.ResourceType,
299              DateCreated = now,
300              DateExpired = null
301            });
302          } else {
303            dimc.Name = r.Name;
304          }
305        }
306      }
307    }
308
309    //// (1) for new slaves (not yet reported in Table DimClients) ...
310    //// and modified slaves (name or parent resource changed) a new DimClient-entry is created
311    //// (2) for already reported removed and modifid clients the expiration date is set
312    //private void UpdateDimClientsTableOld(PersistenceManager pm) {
313    //  var dimClientDao = pm.DimClientDao;
314    //  var slaveDao = pm.SlaveDao;
315    //  var slaves = slaveDao.GetAll();
316    //  var recentlyAddedClients = dimClientDao.GetAllOnlineClients();
317    //  var slaveIds = slaves.Select(x => x.ResourceId);
318
319    //  var removedClientIds = recentlyAddedClients
320    //    .Where(x => !slaveIds.Contains(x.ResourceId))
321    //    .Select(x => x.Id);
322    //  var modifiedClients =
323    //    from slave in slaves
324    //    join client in recentlyAddedClients on slave.ResourceId equals client.ResourceId
325    //    where (slave.Name != client.Name
326    //           || slave.ParentResourceId == null && client.ResourceGroupId != null // because both can be null and null comparison
327    //           || slave.ParentResourceId != null && client.ResourceGroupId == null // does return no entry on the sql server
328    //           || slave.ParentResourceId != client.ResourceGroupId
329    //           || ((slave.ParentResource != null) && slave.ParentResource.ParentResourceId != client.ResourceGroup2Id))
330    //    select new {
331    //      SlaveId = slave.ResourceId,
332    //      ClientId = client.Id
333    //    };
334    //  var clientIds = dimClientDao.GetAllOnlineClients().Select(x => x.ResourceId);
335    //  var modifiedClientIds = modifiedClients.Select(x => x.SlaveId);
336    //  var newClients = slaves
337    //    .Where(x => !clientIds.Contains(x.ResourceId)
338    //                || modifiedClientIds.Contains(x.ResourceId))
339    //    .Select(x => new {
340    //      x.ResourceId,
341    //      x.Name,
342    //      ResourceGroupId = x.ParentResourceId,
343    //      GroupName = x.ParentResource != null ? x.ParentResource.Name : null,
344    //      ResourceGroup2Id = x.ParentResource != null ? x.ParentResource.ParentResourceId : null,
345    //      GroupName2 = x.ParentResource != null ? x.ParentResource.ParentResource != null ? x.ParentResource.ParentResource.Name : null : null
346    //    })
347    //    .ToList();
348
349    //  var clientsToUpdate = removedClientIds.Union(modifiedClients.Select(x => x.ClientId));
350    //  dimClientDao.UpdateExpirationTime(clientsToUpdate, DateTime.Now);
351    //  dimClientDao.Save(newClients.Select(x => new DimClient {
352    //    ResourceId = x.ResourceId,
353    //    Name = x.Name,
354    //    ExpirationTime = null,
355    //    ResourceGroupId = x.ResourceGroupId,
356    //    GroupName = x.GroupName,
357    //    ResourceGroup2Id = x.ResourceGroup2Id,
358    //    GroupName2 = x.GroupName2
359    //  }));
360    //}
361
362
363    private void UpdateFactClientInfoTable(DimTime newTime, PersistenceManager pm) {
364      var factClientInfoDao = pm.FactClientInfoDao;
365      var slaveDao = pm.SlaveDao;
366      var dimClientDao = pm.DimClientDao;
367
368      var newRawFactInfos =
369        from s in slaveDao.GetAll()
370        join c in dimClientDao.GetAllOnlineSlaves() on s.ResourceId equals c.ResourceId
371        join lcf in factClientInfoDao.GetLastUpdateTimestamps() on c.ResourceId equals lcf.ResourceId into joinCf
372        from cf in joinCf.DefaultIfEmpty()
373        select new {
374          ClientId = c.Id,
375          UserId = s.OwnerUserId ?? Guid.Empty,
376          TotalCores = s.Cores ?? 0,
377          FreeCores = s.FreeCores ?? 0,
378          TotalMemory = s.Memory ?? 0,
379          FreeMemory = s.FreeMemory ?? 0,
380          CpuUtilization = s.CpuUtilization,
381          SlaveState = s.SlaveState,
382          IsAllowedToCalculate = s.IsAllowedToCalculate,
383          LastFactTimestamp = cf.Timestamp
384        };
385
386      factClientInfoDao.Save(
387        from x in newRawFactInfos.ToList()
388        let duration = x.LastFactTimestamp != null
389                       ? (int)(newTime.Time - (DateTime)x.LastFactTimestamp).TotalSeconds
390                       : (int)SmallestTimeSpan.TotalSeconds
391        select new FactClientInfo {
392          ClientId = x.ClientId,
393          DimTime = newTime,
394          UserId = x.UserId,
395          NumUsedCores = x.TotalCores - x.FreeCores,
396          NumTotalCores = x.TotalCores,
397          UsedMemory = x.TotalMemory - x.FreeMemory,
398          TotalMemory = x.TotalMemory,
399          CpuUtilization = Math.Round(x.CpuUtilization, 2),
400          SlaveState = x.SlaveState,
401          IdleTime = x.SlaveState == SlaveState.Idle && x.IsAllowedToCalculate ? duration : 0,
402          UnavailableTime = x.SlaveState == SlaveState.Idle && !x.IsAllowedToCalculate ? duration : 0,
403          OfflineTime = x.SlaveState == SlaveState.Offline ? duration : 0,
404          IsAllowedToCalculate = x.IsAllowedToCalculate
405        }
406      );
407    }
408
409    private void UpdateFactProjectInfoTable(DimTime newTime, PersistenceManager pm) {
410      var factProjectInfoDao = pm.FactProjectInfoDao;
411      var dimProjectDao = pm.DimProjectDao;
412      var projectDao = pm.ProjectDao;
413
414      var projectAvailabilityStats = projectDao.GetAvailabilityStatsPerProject();
415      var projectUsageStats = projectDao.GetUsageStatsPerProject();
416      var dimProjects = dimProjectDao.GetAllOnlineProjects().ToList();
417
418      factProjectInfoDao.Save(
419        from dimp in dimProjects
420        let aStats = projectAvailabilityStats.Where(x => x.ProjectId == dimp.ProjectId).SingleOrDefault()
421        let uStats = projectUsageStats.Where(x => x.ProjectId == dimp.ProjectId).SingleOrDefault()
422        select new FactProjectInfo {
423            ProjectId = dimp.Id,
424            DimTime = newTime,
425            NumTotalCores = aStats != null ? aStats.Cores : 0,
426            TotalMemory = aStats != null ? aStats.Memory : 0,
427            NumUsedCores = uStats != null ? uStats.Cores : 0,
428            UsedMemory = uStats != null ? uStats.Memory : 0
429          }
430        );
431    }
432
433    private void UpdateFactTaskTable(PersistenceManager pm) {
434      var factTaskDao = pm.FactTaskDao;
435      var taskDao = pm.TaskDao;
436      var dimClientDao = pm.DimClientDao;
437
438      var factTaskIds = factTaskDao.GetAll().Select(x => x.TaskId);
439      var notFinishedFactTasks = factTaskDao.GetNotFinishedTasks();
440      //var notFinishedFactTasks = factTaskDao.GetNotFinishedTasks().Select(x => new {
441      //  x.TaskId,
442      //  x.LastClientId
443      //});
444
445      // query several properties for all new and not finished tasks
446      // in order to use them later either...
447      // (1) to update the fact task entry of not finished tasks
448      // (2) to insert a new fact task entry for new tasks
449      var newAndNotFinishedTasks =
450        (from task in taskDao.GetAllChildTasks()
451         let stateLogs = task.StateLogs.OrderByDescending(x => x.DateTime)
452         let lastSlaveId = stateLogs.First(x => x.SlaveId != null).SlaveId
453         where (!factTaskIds.Contains(task.TaskId)
454                || notFinishedFactTasks.Select(x => x.TaskId).Contains(task.TaskId))
455         join lastFactTask in notFinishedFactTasks on task.TaskId equals lastFactTask.TaskId into lastFactPerTask
456         from lastFact in lastFactPerTask.DefaultIfEmpty()
457         join client in dimClientDao.GetAllOnlineClients() on lastSlaveId equals client.ResourceId into clientsPerSlaveId
458         from client in clientsPerSlaveId.DefaultIfEmpty()
459         select new {
460           TaskId = task.TaskId,
461           JobId = task.JobId,
462           Priority = task.Priority,
463           CoresRequired = task.CoresNeeded,
464           MemoryRequired = task.MemoryNeeded,
465           State = task.State,
466           StateLogs = stateLogs.OrderBy(x => x.DateTime),
467           LastClientId = client != null
468                          ? client.Id : lastFact != null
469                          ? lastFact.LastClientId : (Guid?)null,
470           NotFinishedTask = notFinishedFactTasks.Any(y => y.TaskId == task.TaskId)
471         }).ToList();
472
473      // (1) update data of already existing facts
474      // i.e. for all in newAndNotFinishedTasks where NotFinishedTask = true
475      foreach (var notFinishedFactTask in notFinishedFactTasks) {
476        var nfftUpdate = newAndNotFinishedTasks.Where(x => x.TaskId == notFinishedFactTask.TaskId).SingleOrDefault();
477        if(nfftUpdate != null) {
478          var taskData = CalculateFactTaskData(nfftUpdate.StateLogs);
479
480          notFinishedFactTask.StartTime = taskData.StartTime;
481          notFinishedFactTask.EndTime = taskData.EndTime;
482          notFinishedFactTask.LastClientId = nfftUpdate.LastClientId;
483          notFinishedFactTask.Priority = nfftUpdate.Priority;
484          notFinishedFactTask.CoresRequired = nfftUpdate.CoresRequired;
485          notFinishedFactTask.MemoryRequired = nfftUpdate.MemoryRequired;
486          notFinishedFactTask.NumCalculationRuns = taskData.CalculationRuns;
487          notFinishedFactTask.NumRetries = taskData.Retries;
488          notFinishedFactTask.WaitingTime = taskData.WaitingTime;
489          notFinishedFactTask.CalculatingTime = taskData.CalculatingTime;
490          notFinishedFactTask.TransferTime = taskData.TransferTime;
491          notFinishedFactTask.TaskState = nfftUpdate.State;
492          notFinishedFactTask.Exception = taskData.Exception;
493          notFinishedFactTask.InitialWaitingTime = taskData.InitialWaitingTime;
494        }
495      }
496
497      // (2) insert facts for new tasks
498      // i.e. for all in newAndNotFinishedTasks where NotFinishedTask = false
499      factTaskDao.Save(
500        from x in newAndNotFinishedTasks
501        where !x.NotFinishedTask
502        let taskData = CalculateFactTaskData(x.StateLogs)
503        select new FactTask {
504          TaskId = x.TaskId,
505          JobId = x.JobId,
506          StartTime = taskData.StartTime,
507          EndTime = taskData.EndTime,
508          LastClientId = x.LastClientId,
509          Priority = x.Priority,
510          CoresRequired = x.CoresRequired,
511          MemoryRequired = x.MemoryRequired,
512          NumCalculationRuns = taskData.CalculationRuns,
513          NumRetries = taskData.Retries,
514          WaitingTime = taskData.WaitingTime,
515          CalculatingTime = taskData.CalculatingTime,
516          TransferTime = taskData.TransferTime,
517          TaskState = x.State,
518          Exception = taskData.Exception,
519          InitialWaitingTime = taskData.InitialWaitingTime
520        });
521
522
523      ////update data of already existing facts
524      //foreach (var notFinishedTask in factTaskDao.GetNotFinishedTasks()) {
525      //  var ntc = newTasks.Where(x => x.TaskId == notFinishedTask.TaskId);
526      //  if (ntc.Any()) {
527      //    var x = ntc.Single();
528      //    var taskData = CalculateFactTaskData(x.StateLogs);
529
530      //    notFinishedTask.StartTime = taskData.StartTime;
531      //    notFinishedTask.EndTime = taskData.EndTime;
532      //    notFinishedTask.LastClientId = x.LastClientId;
533      //    notFinishedTask.Priority = x.Priority;
534      //    notFinishedTask.CoresRequired = x.CoresRequired;
535      //    notFinishedTask.MemoryRequired = x.MemoryRequired;
536      //    notFinishedTask.NumCalculationRuns = taskData.CalculationRuns;
537      //    notFinishedTask.NumRetries = taskData.Retries;
538      //    notFinishedTask.WaitingTime = taskData.WaitingTime;
539      //    notFinishedTask.CalculatingTime = taskData.CalculatingTime;
540      //    notFinishedTask.TransferTime = taskData.TransferTime;
541      //    notFinishedTask.TaskState = x.State;
542      //    notFinishedTask.Exception = taskData.Exception;
543      //    notFinishedTask.InitialWaitingTime = taskData.InitialWaitingTime;
544      //  }
545      //}
546    }
547
548    private string GetUserName(Guid userId) {
549      try {
550        // we cannot use the ServiceLocator.Instance.UserManager since the janitor service
551        // is not hosted in the iis the MemberShip.GetUser method causes exceptions
552        // needs to be further investigated current workaround: use the authenticationcontext
553        // we could also connect to the access service to get the user name
554        using (ASPNETAuthenticationDataContext dc = new ASPNETAuthenticationDataContext()) {
555          var user = dc.aspnet_Users.SingleOrDefault(x => x.UserId == userId);
556          return user != null ? user.UserName : UnknownUserName;
557        }
558      }
559      catch (Exception) {
560        return UnknownUserName;
561      }
562    }
563
564    private class FactTaskData {
565      public int CalculationRuns { get; set; }
566      public int Retries { get; set; }
567      public long CalculatingTime { get; set; }
568      public long WaitingTime { get; set; }
569      public long TransferTime { get; set; }
570      public long InitialWaitingTime { get; set; }
571      public string Exception { get; set; }
572      public DateTime? StartTime { get; set; }
573      public DateTime? EndTime { get; set; }
574    }
575
576    private FactTaskData CalculateFactTaskData(IEnumerable<StateLog> stateLogs) {
577      var factTaskData = new FactTaskData();
578      var enumerator = stateLogs.GetEnumerator();
579      if (enumerator.MoveNext()) {
580        StateLog current = enumerator.Current, first = current, prev = null;
581        while (current != null) {
582          var next = enumerator.MoveNext() ? enumerator.Current : null;
583          int timeSpanInSeconds;
584          if (next != null) {
585            timeSpanInSeconds = (int)(next.DateTime - current.DateTime).TotalSeconds;
586          } else {
587            timeSpanInSeconds = (int)(DateTime.Now - current.DateTime).TotalSeconds;
588            factTaskData.Exception = current.Exception;
589          }
590          switch (current.State) {
591            case TaskState.Calculating:
592              factTaskData.CalculatingTime += timeSpanInSeconds;
593              factTaskData.CalculationRuns++;
594              if (factTaskData.CalculationRuns == 1) {
595                factTaskData.StartTime = current.DateTime;
596                factTaskData.InitialWaitingTime = (int)(current.DateTime - first.DateTime).TotalSeconds;
597              }
598              if (prev != null && prev.State != TaskState.Transferring) {
599                factTaskData.Retries++;
600              }
601              break;
602
603            case TaskState.Waiting:
604              factTaskData.WaitingTime += timeSpanInSeconds;
605              break;
606
607            case TaskState.Transferring:
608              factTaskData.TransferTime += timeSpanInSeconds;
609              break;
610
611            case TaskState.Finished:
612            case TaskState.Failed:
613            case TaskState.Aborted:
614              factTaskData.EndTime = current.DateTime;
615              break;
616          }
617          prev = current;
618          current = next;
619        }
620      }
621      return factTaskData;
622    }
623  }
624}
Note: See TracBrowser for help on using the repository browser.