Bug Fix: Error when assigning devices

The noticeboard listens for updates to user assignments (including who
was previously assigned the device), but was requesting data which no
longer existed (as updates are delayed and buffered for up to 500ms).
This commit is contained in:
Gary Sharp
2014-07-26 12:25:20 +10:00
parent 81d024618a
commit b78ce003a7
+36 -12
View File
@@ -5,7 +5,9 @@ using Disco.Models.Services.Jobs.Noticeboards;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Subjects;
namespace Disco.Services.Jobs.Noticeboards
{
@@ -41,10 +43,19 @@ namespace Disco.Services.Jobs.Noticeboards
"DisplayName"
};
private static Subject<Tuple<List<string>, List<string>>> BufferedUpdateStream;
static HeldDevices()
{
BufferedUpdateStream = new Subject<Tuple<List<string>, List<string>>>();
BufferedUpdateStream
.DelayBuffer(TimeSpan.FromMilliseconds(500))
.SubscribeOn(TaskPoolScheduler.Default)
.Subscribe(ProcessUpdates);
// Subscribe to Repository Notifications
RepositoryMonitor.StreamAfterCommit.Where(e =>
RepositoryMonitor.StreamBeforeCommit.Where(e =>
(e.EntityType == typeof(Job) &&
(e.EventType == RepositoryMonitorEventType.Added ||
e.EventType == RepositoryMonitorEventType.Deleted ||
@@ -65,19 +76,14 @@ namespace Disco.Services.Jobs.Noticeboards
(e.EventType == RepositoryMonitorEventType.Modified && e.ModifiedProperties.Any(p => MonitorUserProperties.Contains(p)))
)
)
.DelayBuffer(TimeSpan.FromMilliseconds(500))
.Subscribe(RepositoryEvent);
}
private static void RepositoryEvent(IEnumerable<RepositoryMonitorEvent> e)
private static void RepositoryEvent(RepositoryMonitorEvent i)
{
List<string> deviceSerialNumbers = new List<string>();
List<string> userIds = new List<string>();
using (DiscoDataContext Database = new DiscoDataContext())
{
foreach (var i in e)
{
if (i.EntityType == typeof(Job))
{
if (i.EventType == RepositoryMonitorEventType.Modified &&
@@ -103,7 +109,7 @@ namespace Disco.Services.Jobs.Noticeboards
}
else
{
var sn = Database.Jobs.Where(j => j.Id == jmnw.JobId).Select(j => j.DeviceSerialNumber).FirstOrDefault();
var sn = i.Database.Jobs.Where(j => j.Id == jmnw.JobId).Select(j => j.DeviceSerialNumber).FirstOrDefault();
if (sn != null)
deviceSerialNumbers.Add(sn);
}
@@ -126,7 +132,7 @@ namespace Disco.Services.Jobs.Noticeboards
var dp = (DeviceProfile)i.Entity;
deviceSerialNumbers.AddRange(
Database.Jobs
i.Database.Jobs
.Where(j => !j.ClosedDate.HasValue && j.Device.DeviceProfileId == dp.Id)
.Select(j => j.DeviceSerialNumber)
);
@@ -136,21 +142,38 @@ namespace Disco.Services.Jobs.Noticeboards
var u = (User)i.Entity;
deviceSerialNumbers.AddRange(
Database.Jobs
i.Database.Jobs
.Where(j => !j.ClosedDate.HasValue && j.Device.AssignedUserId == u.UserId)
.Select(j => j.DeviceSerialNumber)
);
}
if (deviceSerialNumbers.Count > 0 || userIds.Count > 0)
{
i.ExecuteAfterCommit(e =>
{
BufferedUpdateStream.OnNext(Tuple.Create(deviceSerialNumbers, userIds));
});
}
}
deviceSerialNumbers = deviceSerialNumbers.Distinct().ToList();
private static void ProcessUpdates(IEnumerable<Tuple<List<string>, List<string>>> e)
{
using (DiscoDataContext Database = new DiscoDataContext())
{
var deviceSerialNumbers = e.SelectMany(i => i.Item1).Distinct().ToList();
var userIds = e.SelectMany(i => i.Item2).Distinct().ToList();
// Determine Held Devices for Users
if (deviceSerialNumbers.Count > 0)
{
userIds.AddRange(
Database.Devices
.Where(d => d.AssignedUserId != null && deviceSerialNumbers.Contains(d.SerialNumber))
.Select(d => d.AssignedUserId)
);
}
if (userIds.Count > 0)
userIds = userIds.Distinct().ToList();
@@ -173,7 +196,8 @@ namespace Disco.Services.Jobs.Noticeboards
var updates = DeviceSerialNumbers
.Skip(skipAmount).Take(30)
.ToDictionary(dsn => dsn,
dsn => {
dsn =>
{
IHeldDeviceItem item;
items.TryGetValue(dsn, out item);
return item;