From ed15f8b856ead0f52efba1572891e9cda4330644 Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Thu, 9 May 2013 17:02:32 +1000 Subject: [PATCH] Fix: Managed Job Lists --- Disco.BI/BI/JobBI/ManagedJobList.cs | 102 +++++++++++++++++++++------- Disco.BI/Properties/AssemblyInfo.cs | 4 +- 2 files changed, 81 insertions(+), 25 deletions(-) diff --git a/Disco.BI/BI/JobBI/ManagedJobList.cs b/Disco.BI/BI/JobBI/ManagedJobList.cs index e9f604ae..8f858994 100644 --- a/Disco.BI/BI/JobBI/ManagedJobList.cs +++ b/Disco.BI/BI/JobBI/ManagedJobList.cs @@ -15,9 +15,10 @@ namespace Disco.BI.JobBI public class ManagedJobList : JobTableModel, IDisposable { public string Name { get; set; } - public Func, IQueryable> FilterFunction {get;set;} + public Func, IQueryable> FilterFunction { get; set; } public Func, IEnumerable> SortFunction { get; set; } private IDisposable unsubscribeToken; + private object updateLock = new object(); public ManagedJobList Initialize(DiscoDataContext dbContext) { @@ -25,11 +26,21 @@ namespace Disco.BI.JobBI this.Items = this.SortFunction(this.DetermineItems(dbContext, this.FilterFunction(dbContext.Jobs))).ToList(); // Subscribe for Changes + // - Job (or Job Meta) Changes + // - Device Profile Address Changes (for multi-campus Schools) + // - Device Model Description Changes + // - Device's Profile or Model Changes unsubscribeToken = RepositoryMonitor.StreamAfterCommit .Where(n => n.EntityType == typeof(Job) || n.EntityType == typeof(JobMetaWarranty) || n.EntityType == typeof(JobMetaNonWarranty) || - n.EntityType == typeof(JobMetaInsurance)) + n.EntityType == typeof(JobMetaInsurance) || + (n.EventType == RepositoryMonitorEventType.Modified && ( + (n.EntityType == typeof(DeviceProfile) && n.ModifiedProperties.Contains("DefaultOrganisationAddress")) || + (n.EntityType == typeof(DeviceModel) && n.ModifiedProperties.Contains("Description")) + )) || + (n.EntityType == typeof(Device) && n.ModifiedProperties.Contains("DeviceProfileId") || n.ModifiedProperties.Contains("DeviceModelId")) + ) .Subscribe(JobNotification); return this; @@ -37,44 +48,89 @@ namespace Disco.BI.JobBI private void JobNotification(RepositoryMonitorEvent e) { - int jobId; + List jobIds = null; + JobTableItemModel[] existingItems = null; if (e.EntityType == typeof(Job)) - jobId = ((Job)e.Entity).Id; + jobIds = new List() { ((Job)e.Entity).Id }; else if (e.EntityType == typeof(JobMetaWarranty)) - jobId = ((JobMetaWarranty)e.Entity).JobId; + jobIds = new List() { ((JobMetaWarranty)e.Entity).JobId }; else if (e.EntityType == typeof(JobMetaNonWarranty)) - jobId = ((JobMetaNonWarranty)e.Entity).JobId; + jobIds = new List() { ((JobMetaNonWarranty)e.Entity).JobId }; else if (e.EntityType == typeof(JobMetaInsurance)) - jobId = ((JobMetaInsurance)e.Entity).JobId; + jobIds = new List() { ((JobMetaInsurance)e.Entity).JobId }; else - return; // Subscription should never reach + if (e.EntityType == typeof(DeviceProfile)) + { + int deviceProfileId = ((DeviceProfile)e.Entity).Id; + existingItems = this.Items.Where(i => i.DeviceProfileId == deviceProfileId).ToArray(); + } + else + if (e.EntityType == typeof(DeviceModel)) + { + int deviceModelId = ((DeviceModel)e.Entity).Id; + existingItems = this.Items.Where(i => i.DeviceModelId == deviceModelId).ToArray(); + } + else + if (e.EntityType == typeof(Device)) + { + string deviceSerialNumber = ((Device)e.Entity).SerialNumber; + existingItems = this.Items.Where(i => i.DeviceSerialNumber == deviceSerialNumber).ToArray(); + } + else + return; // Subscription should never reach - var existingItem = this.Items.FirstOrDefault(i => i.Id == jobId); - var updatedItem = this.DetermineItems(e.dbContext, this.FilterFunction(e.dbContext.Jobs.Where(j => j.Id == jobId))); - - var updatedItems = this.Items.ToList(); - - // Remove Existing - if (existingItem != null) - updatedItems.Remove(existingItem); - - if (updatedItem.Count > 0) + if (jobIds == null) { - // Add Item - updatedItems.Add(updatedItem.First()); + if (existingItems == null) + throw new InvalidOperationException("Notification algorithm didn't indicate any Jobs for update"); + else + jobIds = existingItems.Select(i => i.Id).ToList(); } - // Reorder - this.Items = this.SortFunction(updatedItems).ToList(); + if (jobIds.Count == 0) + return; + else + UpdateJobs(e.dbContext, jobIds, existingItems); + } + + private void UpdateJobs(DiscoDataContext dbContext, List jobIds, JobTableItemModel[] existingItems = null) + { + lock (updateLock) + { + // Check for existing items, if not handed them + if (existingItems == null) + existingItems = this.Items.Where(i => jobIds.Contains(i.Id)).ToArray(); + + var updatedItems = this.DetermineItems(dbContext, this.FilterFunction(dbContext.Jobs.Where(j => jobIds.Contains(j.Id)))); + + var refreshedList = this.Items.ToList(); + + // Remove Existing + if (existingItems.Length > 0) + foreach (var existingItem in existingItems) + refreshedList.Remove(existingItem); + + // Add Updated Items + if (updatedItems.Count > 0) + foreach (var updatedItem in updatedItems) + refreshedList.Add(updatedItem); + + // Reorder + this.Items = this.SortFunction(refreshedList).ToList(); + } } public void Dispose() { - unsubscribeToken.Dispose(); + if (unsubscribeToken != null) + { + unsubscribeToken.Dispose(); + unsubscribeToken = null; + } } } } diff --git a/Disco.BI/Properties/AssemblyInfo.cs b/Disco.BI/Properties/AssemblyInfo.cs index afb25697..246b7237 100644 --- a/Disco.BI/Properties/AssemblyInfo.cs +++ b/Disco.BI/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0506.2022")] -[assembly: AssemblyFileVersion("1.2.0506.2022")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.0509.1622")] +[assembly: AssemblyFileVersion("1.2.0509.1622")] \ No newline at end of file