/// <summary> /// Atomically marks a shared <see cref="CachedSession"/> in the session cache as no longer being used by the /// current caller for the <paramref name="partitionId"/>. This is used to track the number of concurrent users /// so cache eviction policies don't remove an entry while it's still potentially in use. /// </summary> /// /// <param name="partitionId">The partition id for a session.</param> private void ReleaseShared(string partitionId) { try { CachedSession cacheItem = SessionCache.Get <CachedSession>(partitionId); // Decrements the usage counter of the entry cacheItem.DecrementUsageTracker(); // If we know it's still in use, don't expire it yet if (!cacheItem.IsUsed()) { // No longer in use, so now kickoff the expire timer var cacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.Low) .SetSlidingExpiration(TimeSpan.FromMilliseconds(cryptoPolicy.GetSessionCacheExpireMillis())) .RegisterPostEvictionCallback((id, value, reason, state) => { ((CachedSession)value).GetEnvelopeEncryptionJsonImpl().Dispose(); }); SessionCache.Set(partitionId, cacheItem, cacheEntryOptions); } } catch (Exception e) { Logger.LogError(e, "Unexpected exception during dispose"); } }
/// <inheritdoc/> public virtual void Dispose() { try { // only close system key cache since we invoke its creation systemKeyCache.Dispose(); } catch (Exception e) { Logger.LogError(e, "unexpected exception during skCache close"); } // Actually dispose of all the remaining sessions that might be active in the cache. lock (SessionCache) { foreach (KeyValuePair <string, object> sessionCacheKey in semaphoreLocks) { CachedSession cachedSession = SessionCache.Get <CachedSession>(sessionCacheKey.Key); // We need to check this to ensure that the entry was not removed by the expiration policy if (cachedSession != null) { // actually close the real thing cachedSession.GetEnvelopeEncryptionJsonImpl().Dispose(); } // now remove the entry from the cache SessionCache.Remove(sessionCacheKey.Key); } } }
/// <summary> /// Atomically acquires a shared <see cref="CachedSession"/> from the session cache for the /// <paramref name="partitionId"/>, creating a new one using the given function if needed. This is used to track /// the number of concurrent users so cache eviction policies don't remove an entry while it's still potentially /// in use. /// </summary> /// /// <returns>The cached session that's mapped for the given <paramref name="partitionId"/>.</returns> /// /// <param name="createSessionFunc">The function to create a new session if there is no current mapping.</param> /// <param name="partitionId">The partition id for a session.</param> private CachedSession AcquireShared( Func <EnvelopeEncryptionJsonImpl> createSessionFunc, string partitionId) { object getCachedItemLock = semaphoreLocks.GetOrAdd(partitionId, new object()); CachedSession cachedItem; // TryGetValue is not thread safe and hence we need a lock lock (getCachedItemLock) { if (!SessionCache.TryGetValue(partitionId, out cachedItem)) { // If the cache size is greater than the maximum count, compact the cache // This will remove all the unused sessions if (SessionCache.Count >= cryptoPolicy.GetSessionCacheMaxSize()) { SessionCache.Compact(CompactionPercentage); } // Creating for first time cachedItem = new CachedSession(createSessionFunc(), partitionId, this); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.NeverRemove); // Save data in cache. SessionCache.Set(partitionId, cachedItem, cacheEntryOptions); } // Increment the usage counter of the entry cachedItem.IncrementUsageTracker(); } return(cachedItem); }
private void AddSession(CachedSession session) { _list.Insert(0, new ApiModel(session)); while (_list.Count > SaveCount) { _list.RemoveAt(SaveCount); } }
private void AddApi(string type, CachedSession oSession) { if (type == "startnext") { datastring = string.Empty; } datastring += $",\"{type}\":{{\"api\":\"{oSession.Session.PathAndQuery.Substring(8)}\",\"data\":{oSession.JsonResponse}}}"; }
private static void ExceptionCatcher(Action <CachedSession> action, CachedSession parameter) { try { action(parameter); } catch (Exception ex) { Models.Status.Current.LatestException = ex; } }
private void EscapeHandler(CachedSession x) { if (lastescapeinfo != null) { FindShip(lastescapeinfo.api_escape_idx[0]).IsEscaped = true; if (lastescapeinfo.api_tow_idx != null) { FindShip(lastescapeinfo.api_tow_idx[0]).IsEscaped = true; } } }
public void Save(CachedSession oSession) { try { Directory.CreateDirectory("logs"); using (var writer = File.CreateText(@"information\masterdata.json")) { writer.Write(oSession.JsonResponse.UnicodeDecode()); writer.Flush(); } } catch { } }
public void Save(CachedSession oSession) { try { Directory.CreateDirectory("logs"); using (var writer = File.CreateText(@"information\masterdata.json")) { writer.Write(oSession.JsonResponse.UnicodeDecode()); writer.Flush(); } } catch { } }
public void ForceRefreshSession(string sessionID) { CachedSession cachedSession = GetSessionBySessionID(sessionID); if (cachedSession != null) { lock (_lock) { _cachedSessionBySessionID.Remove(sessionID); } } Context context = new Context(); Session session = context.Sessions.FirstOrDefault(s => s.SessionStateID == sessionID); if (session != null) { lock (_lock) { AddCachedSession(session); } } }
private void AddApi(string type, CachedSession oSession) { if (type == "startnext") datastring = string.Empty; datastring += $",\"{type}\":{{\"api\":\"{oSession.Session.PathAndQuery.Substring(8)}\",\"data\":{oSession.JsonResponse}}}"; }
public ApiModel(CachedSession oSession) { Session = oSession; }
private void AddSession(CachedSession session) { _list.Insert(0, new ApiModel(session)); while (_list.Count > SaveCount) _list.RemoveAt(SaveCount); }
public ApiModel(CachedSession oSession) { Session = oSession; }