git_bsmd/nsw/Source/bsmd.LockingService/LockingService.svc.cs
Daniel Schick 4d76d7191d Neue Version 3.6.2.0:
- Speichern
- Locking (noch nicht funktional)
- Visit-Id anfordern (noch nicht funktional)
- neuer Splashscreen
2017-05-28 13:00:02 +00:00

133 lines
4.2 KiB
C#

// Copyright (c) 2017 schick Informatik
using System;
using System.Collections.Generic;
using log4net;
using bsmd.database;
using System.ServiceModel.Activation;
using System.Timers;
namespace bsmd.LockingService
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class LockingService : IService
{
private static ILog _log = LogManager.GetLogger(typeof(LockingService));
private static Dictionary<Guid, LockEntry> lockDict = new Dictionary<Guid, LockEntry>();
private static Timer staleTimer = new Timer(5000); // alle 5 Sekunden prüfen
private const int staleTimeoutSeconds = 120; // wenn sie eine Anwendung 2 Minuten nicht meldet, werden die Locks freigegeben
static LockingService()
{
staleTimer.Elapsed += StaleTimer_Elapsed;
}
private static void StaleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (lockDict)
{
List<Guid> deleteList = new List<Guid>();
foreach (Guid key in lockDict.Keys)
if ((DateTime.Now - lockDict[key].lockAquired).TotalSeconds > staleTimeoutSeconds)
deleteList.Add(key);
foreach (Guid key in deleteList)
{
_log.WarnFormat("Stale remove message core id {0}, User {1}", key, lockDict[key].userId);
lockDict.Remove(key);
}
}
}
private ILog log = LogManager.GetLogger(typeof(LockingService));
#region Implementation IService
public Guid Lock(Guid messageCoreId, Guid userId)
{
Guid result = Guid.Empty;
lock (lockDict)
{
if (!lockDict.ContainsKey(messageCoreId))
{
LockEntry le = new LockEntry();
le.lockAquired = DateTime.Now;
le.userId = userId;
lockDict.Add(messageCoreId, le);
}
else
{
if (lockDict[messageCoreId].userId == userId)
{
// this means "refresh"
lockDict[messageCoreId].lockAquired = DateTime.Now;
}
else
{
// lock taken by somebody else..
result = lockDict[messageCoreId].userId;
}
}
}
return result;
}
public void Unlock(Guid messageCoreId, Guid userId)
{
lock(lockDict)
{
if(lockDict.ContainsKey(messageCoreId))
{
if (lockDict[messageCoreId].userId == userId)
lockDict.Remove(messageCoreId);
}
}
}
public void LockRefresh(List<Guid> currentLocks, Guid userId)
{
foreach (Guid messageCoreId in currentLocks)
this.Lock(messageCoreId, userId);
}
public void Log(string msg, string host, Guid userId)
{
log.Info(string.Format("{0} {1}:{2}", host, userId, msg));
}
public List<CoreLock> GetLocks()
{
List<CoreLock> result = new List<CoreLock>();
lock (lockDict)
{
foreach (Guid messageCoreId in lockDict.Keys)
{
CoreLock coreLock = new CoreLock();
coreLock.CoreId = messageCoreId;
coreLock.UserId = lockDict[messageCoreId].userId;
result.Add(coreLock);
}
}
return result;
}
#endregion
#region class LockEntry
internal class LockEntry
{
public DateTime lockAquired = DateTime.Now;
public Guid userId;
}
#endregion
}
}