Files
Disco/Disco.Services/Jobs/JobQueues/Cache.cs
T
Gary Sharp 4c3a68da30 Feature #26: User Flags
Flags can be associated with Users. Includes minor updates to Job Queues
and improved visibility of user information.
2014-06-10 17:16:24 +10:00

150 lines
5.6 KiB
C#

using Disco.Data.Repository;
using Disco.Models.Repository;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Disco.Services.Jobs.JobQueues
{
internal class Cache
{
private ConcurrentDictionary<int, JobQueueToken> _Cache;
private Dictionary<string, List<JobQueueToken>> _SubjectCache;
private ReadOnlyCollection<KeyValuePair<int, string>> _SlaOptions;
public Cache(DiscoDataContext Database)
{
Initialize(Database);
}
private void Initialize(DiscoDataContext Database)
{
// Queues from Database
var queues = Database.JobQueues.ToList();
// Add Queues to In-Memory Cache
this._Cache = new ConcurrentDictionary<int, JobQueueToken>(queues.Select(q => new KeyValuePair<int, JobQueueToken>(q.Id, JobQueueToken.FromJobQueue(q))));
// Calculate Queue Subject Cache
CalculateSubjectCache();
#region Predefined Options
// SLA Options
if (this._SlaOptions == null)
{
this._SlaOptions = new List<KeyValuePair<int, string>>()
{
new KeyValuePair<int, string>(0, "<None>"),
new KeyValuePair<int, string>(15, "15 minutes"),
new KeyValuePair<int, string>(30, "30 minutes"),
new KeyValuePair<int, string>(60, "1 hour"),
new KeyValuePair<int, string>(60 * 2, "2 hours"),
new KeyValuePair<int, string>(60 * 4, "4 hours"),
new KeyValuePair<int, string>(60 * 8, "8 hours"),
new KeyValuePair<int, string>(60 * 24, "1 day"),
new KeyValuePair<int, string>(60 * 24 * 2, "2 days"),
new KeyValuePair<int, string>(60 * 24 * 3, "3 days"),
new KeyValuePair<int, string>(60 * 24 * 4, "4 days"),
new KeyValuePair<int, string>(60 * 24 * 5, "5 days"),
new KeyValuePair<int, string>(60 * 24 * 6, "6 days"),
new KeyValuePair<int, string>(60 * 24 * 7, "1 week"),
new KeyValuePair<int, string>(60 * 24 * 7 * 2, "2 weeks"),
new KeyValuePair<int, string>(60 * 24 * 7 * 3, "3 weeks"),
new KeyValuePair<int, string>(60 * 24 * 7 * 4, "4 weeks"),
new KeyValuePair<int, string>(60 * 24 * 7 * 4 * 2, "2 months"),
new KeyValuePair<int, string>(60 * 24 * 7 * 4 * 3, "3 months"),
new KeyValuePair<int, string>(60 * 24 * 7 * 4 * 4, "4 months"),
new KeyValuePair<int, string>(60 * 24 * 7 * 4 * 5, "5 months"),
new KeyValuePair<int, string>(60 * 24 * 7 * 4 * 6, "6 months")
}.AsReadOnly();
}
#endregion
}
private void CalculateSubjectCache()
{
_SubjectCache = (from c in _Cache.Values.ToList()
from s in c.SubjectIds
group c by s into subjectId
select subjectId).ToDictionary(g => g.Key.ToLower(), g => g.ToList());
}
public ReadOnlyCollection<KeyValuePair<int, string>> SlaOptions { get { return this._SlaOptions; } }
public JobQueueToken UpdateQueue(JobQueue JobQueue)
{
var token = JobQueueToken.FromJobQueue(JobQueue);
JobQueueToken existingToken;
if (_Cache.TryGetValue(JobQueue.Id, out existingToken))
{
if (_Cache.TryUpdate(JobQueue.Id, token, existingToken))
{
if (existingToken.JobQueue.SubjectIds != token.JobQueue.SubjectIds)
CalculateSubjectCache();
return token;
}
else
return null;
}
else
{
if (_Cache.TryAdd(JobQueue.Id, token))
{
CalculateSubjectCache();
return token;
}
else
return null;
}
}
public bool RemoveQueue(int JobQueueId)
{
JobQueueToken token;
if (_Cache.TryRemove(JobQueueId, out token))
{
CalculateSubjectCache();
return true;
}
else
{
return false;
}
}
public JobQueueToken GetQueue(int JobQueueId)
{
JobQueueToken token;
if (_Cache.TryGetValue(JobQueueId, out token))
return token;
else
return null;
}
public ReadOnlyCollection<JobQueueToken> GetQueues()
{
return _Cache.Values.ToList().AsReadOnly();
}
private IEnumerable<JobQueueToken> GetQueuesForSubject(string SubjectId)
{
List<JobQueueToken> tokens;
if (_SubjectCache.TryGetValue(SubjectId.ToLower(), out tokens))
return tokens;
else
return Enumerable.Empty<JobQueueToken>();
}
public ReadOnlyCollection<JobQueueToken> GetQueuesForSubject(IEnumerable<string> SubjectIds)
{
return SubjectIds.SelectMany(sid => GetQueuesForSubject(sid)).Distinct().ToList().AsReadOnly();
}
public void ReInitializeCache(DiscoDataContext Database)
{
Initialize(Database);
}
}
}