using BS.SharedLauncher.DataContract; using BS.SharedLauncher.Exceptions; using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading; using System.Threading.Tasks; namespace BeWo.Service.ServiceUtils.Update { public static class UpdateServerSessionManager { private static string _Lock => string.Empty; private static readonly Dictionary _UpdateServerSessions = new Dictionary(); public static UpdateServerSession CurrentSession(string session_id) { try { Monitor.Enter(_Lock); return _UpdateServerSessions.TryGetValue(session_id, out var session) ? session : null; } catch (Exception e) { throw new FaultException(e.StackTrace + e.InnerException != null ? e.InnerException.Message : string.Empty); } finally { Monitor.Exit(_Lock); } } public static string GenerateUniqueSessionId() { var session_id = Guid.NewGuid().ToString(); if (_UpdateServerSessions.ContainsKey(session_id)) return GenerateUniqueSessionId(); return session_id; } public static void CreateSession(UpdatePlanResponse res, string tenant) { try { Monitor.Enter(_Lock); var session_id = GenerateUniqueSessionId(); if (_UpdateServerSessions.ContainsKey(session_id)) throw new UpdateException("session id generation error"); var session = new UpdateServerSession() { Id = session_id, Tenant = tenant, Created = DateTime.Now, Timeout = DateTime.Now.AddMinutes(10), FileLimiterDict = res.FilesToRequest.ToDictionary(file => file.RelativePath, file => new UpdateFileLimiter() { RequestsLeft = 5, UpdateFile = file }) }; _UpdateServerSessions.Add(session_id, session); res.Session_Id = session_id; } finally { Monitor.Exit(_Lock); } } public static void CloseSession(string session_id) { try { Monitor.Enter(_Lock); _UpdateServerSessions.Remove(session_id); CheckForTimeoutSessions(); } finally { Monitor.Exit(_Lock); } } public static void CheckForTimeoutSessions() { try { Monitor.Enter(_Lock); foreach (var key_pair in _UpdateServerSessions) { var session_id = key_pair.Key; var session = key_pair.Value; if (session.IsTimeouted) _UpdateServerSessions.Remove(session_id); } } finally { Monitor.Exit(_Lock); } } public static void LoadAbsolutePath(UpdateFileRequest request) { try { Monitor.Enter(_Lock); var file_id = request.UpdateFile.RelativePath; var session_id = request.UpdateSessionId; var session = _UpdateServerSessions[session_id]; var limiter = session.FileLimiterDict[file_id]; request.UpdateFile.AbsolutePath = limiter.UpdateFile.AbsolutePath; limiter.RequestsLeft--; if (!limiter.CanRequestMore) session.FileLimiterDict.Remove(file_id); if (!session.FileLimiterDict.Any()) CloseSession(session_id); } finally { Monitor.Exit(_Lock); } } } }