Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs @ 17475

Last change on this file since 17475 was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

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