Files
Disco/Disco.Services/Jobs/Statistics/DailyOpenedClosed.cs
T
Gary Sharp 27c21175d7 Certificate/wireless plugins; major refactoring
Migrate much of BI to Services.
Added Wireless Profile Provider plugin feature.
Added Certificate Authority Provider plugin feature.
Modified Certificate Provider plugin feature.
Database migration v17, for Device Profiles.
Enrolment Client Updated to support CA Certificates, Wireless Profiles
and Hardware Info.
New Client Enrolment Protocol to support new features.
Plugin Manifest Generator added to main solution.
Improved AD search performance.
2016-09-28 20:17:55 +10:00

173 lines
6.7 KiB
C#

using Disco.Data.Repository;
using Disco.Data.Repository.Monitor;
using Disco.Models.Repository;
using Disco.Models.Services.Job.Statistics;
using Disco.Services.Tasks;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
namespace Disco.Services.Jobs.Statistics
{
public class DailyOpenedClosed : ScheduledTask
{
private static List<DailyOpenedClosedItem> _data;
private static object _dataLock = new object();
private static IDisposable _streamSubscription;
public override string TaskName { get { return "Job Statistics - Daily Opened/Closed Task"; } }
public override bool SingleInstanceTask { get { return true; } }
public override bool CancelInitiallySupported { get { return false; } }
public override bool LogExceptionsOnly { get { return true; } }
public override void InitalizeScheduledTask(DiscoDataContext Database)
{
// Trigger Daily @ 12:29am
TriggerBuilder triggerBuilder = TriggerBuilder.Create().WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(0, 29));
this.ScheduleTask(triggerBuilder);
}
protected override void ExecuteTask()
{
using (var database = new DiscoDataContext())
{
UpdateDataHistory(database, true);
}
}
private static void UpdateDataHistory(DiscoDataContext Database, bool Refresh = false)
{
DateTime historyEnd = DateTime.Now.Date;
if (Refresh || _data == null || _data.Count == 0 || _data.Last().Timestamp < historyEnd)
{
lock (_dataLock)
{
if (Refresh || _data == null || _data.Count == 0 || _data.Last().Timestamp < historyEnd)
{
DateTime historyStart = DateTime.Now.AddDays(-28).Date;
// Initialize Memory Store
List<DailyOpenedClosedItem> resultData;
if (Refresh || _data == null)
resultData = new List<DailyOpenedClosedItem>();
else
resultData = _data;
// Remove Old Data
while (resultData.Count > 0 && resultData[0].Timestamp < historyStart)
resultData.RemoveAt(0);
// Calculate Update Scope
DateTime processDate = historyStart;
if (resultData.Count > 0)
processDate = resultData.Last().Timestamp.AddDays(-1);
// Cache Data
while (processDate <= historyEnd)
{
resultData.Add(Data(Database, processDate));
processDate = processDate.AddDays(1);
}
_data = resultData;
// Subscribe to Live Repository Events
if (_streamSubscription != null)
_streamSubscription.Dispose();
_streamSubscription = RepositoryMonitor.StreamBeforeCommit.Where(
e => e.EntityType == typeof(Job) &&
(e.EventType == RepositoryMonitorEventType.Added || (e.EventType == RepositoryMonitorEventType.Modified && e.ModifiedProperties.Contains("ClosedDate")))).Subscribe(RepositoryEvent_JobChange);
}
}
}
}
private static void RepositoryEvent_JobChange(RepositoryMonitorEvent e)
{
if (e.EventType == RepositoryMonitorEventType.Added)
{
// New Job
var todaysStats = _data.Last();
todaysStats.OpenedJobs += 1;
todaysStats.TotalJobs += 1;
}
else
{
DateTime? previousValue = e.GetPreviousPropertyValue<DateTime?>("ClosedDate");
if (previousValue.HasValue)
{
// Remove Statistics
var statItem = _data.FirstOrDefault(i => i.Timestamp == previousValue.Value.Date);
if (statItem != null)
{
statItem.ClosedJobs -= 1;
statItem.TotalJobs += 1;
}
foreach (var affectedStat in _data.Where(i => i.Timestamp > previousValue))
{
affectedStat.TotalJobs += 1;
}
}
}
DateTime? currentValue = e.GetCurrentPropertyValue<DateTime?>("ClosedDate");
if (currentValue.HasValue)
{
// Add Statistics
// Remove Statistics
var statItem = _data.FirstOrDefault(i => i.Timestamp == currentValue.Value.Date);
if (statItem != null)
{
statItem.ClosedJobs += 1;
statItem.TotalJobs -= 1;
}
foreach (var affectedStat in _data.Where(i => i.Timestamp > currentValue))
{
affectedStat.TotalJobs -= 1;
}
}
}
private static DailyOpenedClosedItem Data(DiscoDataContext Database, DateTime ProcessDate)
{
DateTime processDateStart = ProcessDate;
DateTime processDateEnd = ProcessDate.AddDays(1);
int totalJobs = Database.Jobs.Where(j => j.OpenedDate < processDateEnd && (!j.ClosedDate.HasValue || j.ClosedDate > processDateEnd)).Count();
int openedJobs = Database.Jobs.Where(j => j.OpenedDate > processDateStart && j.OpenedDate < processDateEnd).Count();
int closedJobs = Database.Jobs.Where(j => j.ClosedDate > processDateStart && j.ClosedDate < processDateEnd).Count();
return new DailyOpenedClosedItem()
{
Timestamp = ProcessDate,
TotalJobs = totalJobs,
OpenedJobs = openedJobs,
ClosedJobs = closedJobs
};
}
public static List<DailyOpenedClosedItem> Data(DiscoDataContext Database, bool FilterUnimportantWeekends = false)
{
List<DailyOpenedClosedItem> resultData;
UpdateDataHistory(Database);
if (FilterUnimportantWeekends)
resultData = _data.Where(i => (i.Timestamp.DayOfWeek != DayOfWeek.Saturday && i.Timestamp.DayOfWeek != DayOfWeek.Sunday) ||
(i.OpenedJobs > 0 || i.ClosedJobs > 0)).ToList();
else
resultData = _data.ToList();
return resultData;
}
}
}