/// <summary> /// Disposes of the resources (other than memory) used by the module that implements /// <see cref="System.Web.IHttpModule"/>. /// </summary> /// <remarks> /// Dispose performs any final cleanup work prior to removal of the module from /// the execution pipeline. /// </remarks> void IHttpModule.Dispose() { if (NCacheLog != null) { NCacheLog.Info("NSessionStateModule disposed"); } }
private void OnAppDomainUnload(object unusedObject, EventArgs unusedEventArgs) { try { System.Threading.Thread.GetDomain().DomainUnload -= LegacyProvider.s_onAppDomainUnload; if (_cache != null) { lock (s_dataLock) { s_cacheNeedInit = true; _cache.Dispose(); _cache = null; } } if (_logs) { NCacheLog.Info(" disposed"); } } catch (Exception exc) { RaiseException(exc); } finally { } }
protected DistributionMaps GetMapsOnNodeJoining(DistributionInfoData distInfoData) { if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.GetMapsOnNodeJoining()", "Total Data Size : " + TotalDataSize.ToString()); } ArrayList tmpMap = null; Hashtable bucketsOwnershipMap = null; ArrayList partitionNodes = new ArrayList(); ArrayList newHashMap = DistributeHashMap.BalanceBuckets(distInfoData, _lastCreatedHashMap, _bucketsStats, _existingMembers, _cacheSizePerNode, NCacheLog); _existingMembers.Add(distInfoData.AffectedNode.NodeAddress); tmpMap = ChangeOwnerShip(newHashMap, distInfoData.AffectedNode.NodeAddress); _lastCreatedHashMap = tmpMap.Clone() as ArrayList; bucketsOwnershipMap = GetBucketsOwnershipMap(_lastCreatedHashMap); if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.GetMaps()", "Sending new map as a new node joined the cluster"); } return(new DistributionMaps(_lastCreatedHashMap, bucketsOwnershipMap)); }
/// <summary> /// Locks the buckets which are under the process of state transfer. A locked /// bucket can not be assigned to a node while loadbalancing. Only a coordinator /// node can lock the buckets. /// </summary> /// <param name="buckets"></param> /// <param name="requestingNode"></param> /// <returns></returns> public virtual Hashtable LockBuckets(ArrayList buckets, Address requestingNode) { ArrayList lockAcquired = new ArrayList(); ArrayList ownerChanged = new ArrayList(); Hashtable result = new Hashtable(); Sync.AcquireWriterLock(Timeout.Infinite); try { if (buckets != null) { IEnumerator ie = buckets.GetEnumerator(); while (ie.MoveNext()) { lock (InstalledHashMap.SyncRoot) { HashMapBucket bucket = (HashMapBucket)InstalledHashMap[(int)ie.Current]; if (requestingNode.Equals(bucket.TempAddress)) { if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.lockbuckets", "acquired locked on bucket [" + bucket.BucketId + "] by " + requestingNode); } bucket.Status = BucketStatus.UnderStateTxfr; if (!lockAcquired.Contains(ie.Current)) { lockAcquired.Add(ie.Current); } } else if (!ownerChanged.Contains(ie.Current)) { if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.lockbuckets", "bucket [" + bucket.BucketId + "] owner ship is changed; new owner is " + bucket.TempAddress); } ownerChanged.Add(ie.Current); } } } } } catch (Exception e) { NCacheLog.Error("DistributionMgr.lockbuckets", e.ToString()); return(result); } finally { Sync.ReleaseWriterLock(); } result[BucketLockResult.OwnerChanged] = ownerChanged; result[BucketLockResult.LockAcquired] = lockAcquired; return(result); }
public void UpdateBucketStats(NodeInfo localNode) { try { Sync.AcquireWriterLock(Timeout.Infinite); if (localNode == null) { return; } if (_bucketsStats == null) { _bucketsStats = new Hashtable(); } if (localNode.Statistics != null && localNode.Statistics.LocalBuckets != null) { Hashtable bucketStats = localNode.Statistics.LocalBuckets.Clone() as Hashtable; if (bucketStats != null) { IDictionaryEnumerator ide = bucketStats.GetEnumerator(); while (ide.MoveNext()) { //muds: //see if this node is the permanent owner of the bucket //otherwise its quite possible that we override the //stats of the bucket from the temporary owner. HashMapBucket bucket = (HashMapBucket)_installedHashMap[(int)ide.Key]; if (bucket.PermanentAddress.Equals(localNode.Address)) { BucketStatistics stats = ide.Value as BucketStatistics; _bucketsStats[ide.Key] = ide.Value; } else { } } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.UpdateBucketStats()", "bucketStats = " + _bucketsStats == null ? "null" : _bucketsStats.Count.ToString()); } } } catch (Exception e) { if (NCacheLog.IsErrorEnabled) { NCacheLog.Error("DistributionMgr.UpdateBucketStats()", e.ToString()); } } finally { Sync.ReleaseWriterLock(); } }
private void InitializeCache() { lock (s_dataLock) { try { if (_cache == null) { LegacyProvider.s_onAppDomainUnload = new EventHandler(OnAppDomainUnload); System.Threading.Thread.GetDomain().DomainUnload += LegacyProvider.s_onAppDomainUnload; if (_logs || _detailedLogs) { if (_ncacheLog == null) { _ncacheLog = new NCacheLogger(); _ncacheLog.Initialize(LoggerNames.SessionStoreProvider, _cacheId); if (_detailedLogs) { NCacheLog.SetLevel("all"); } else { if (_logs) { NCacheLog.SetLevel("info"); } } } } if (_isLocationAffinityEnabled) { _cache = new RegionalCache(_ncacheLog, NCacheSessionStateConfigReader.LoadSessionLocationSettings()); } else { _cache = new SingleRegionCache(_operationRetry, _operationRetryInterval); } _cache.InitializeCache(_cacheId); _cache.ExceptionsEnabled = true; s_cacheNeedInit = false; if (_logs) { NCacheLog.Info("NSessionStoreProvider initialized"); } Thread.Sleep(_inprocDelay); } } catch (Exception exc) { _cache = null; // so that next time cache can be initialized. Check the above condition if(_cache == null) RaiseException(exc); } } }
/// <summary> /// Returns the location identifier for this HttpRequest context. Response cookies are searched first /// and if no cookie is found then Requeset cookies are searched for location identifier. /// If there isno cookie in Request or Response then the Location Identifier in the SessionId id returned. /// </summary> /// <param name="context">Context of current HttpRequest</param> /// <param name="sessionId">SessionId for the Request</param> /// <returns>Location Identifer if cookie is found other wise the sessionId is returned.</returns> private string GetLocationID(HttpContext context, string sessionId) { string locationID = sessionId; if (_isLocationAffinityEnabled) { try { if (context.Response.Cookies.Get(LOC_IDENTIFIER) == null) { context.Response.Cookies.Remove(LOC_IDENTIFIER); } else if (string.IsNullOrEmpty(context.Response.Cookies.Get(LOC_IDENTIFIER).Value)) { context.Response.Cookies.Remove(LOC_IDENTIFIER); } else { if (NCacheLog != null) { NCacheLog.Info(sessionId + " :" + "New Location in Response Cookie = " + context.Response.Cookies.Get(LOC_IDENTIFIER).Value); } return(context.Response.Cookies.Get(LOC_IDENTIFIER).Value); } if (context.Request.Cookies.Get(LOC_IDENTIFIER) == null) { context.Request.Cookies.Remove(LOC_IDENTIFIER); } else if (string.IsNullOrEmpty(context.Request.Cookies.Get(LOC_IDENTIFIER).Value)) { context.Request.Cookies.Remove(LOC_IDENTIFIER); } else { if (NCacheLog != null) { NCacheLog.Info(sessionId + " :" + "New Location in Request Cookie = " + context.Request.Cookies.Get(LOC_IDENTIFIER).Value); } return(context.Request.Cookies.Get(LOC_IDENTIFIER).Value); } } catch (Exception e) { if (NCacheLog != null) { NCacheLog.Error(sessionId + " :" + e.ToString()); } } } return(locationID); }
/// <summary> /// Set the status of the bucket to state transfer and in this way this /// bucket becomes locked. A locked bucket can not be assigned during /// loadbalancing. /// </summary> /// <param name="buckets"></param> /// <param name="node"></param> public void ChangeBucketStatusToStateTransfer(ArrayList buckets, Address node) { Sync.AcquireWriterLock(Timeout.Infinite); try { if (buckets != null) { IEnumerator ie = buckets.GetEnumerator(); while (ie.MoveNext()) { lock (InstalledHashMap.SyncRoot) { HashMapBucket bucket = (HashMapBucket)InstalledHashMap[(int)ie.Current]; if (node.Equals(bucket.TempAddress)) { bucket.Status = BucketStatus.UnderStateTxfr; if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.ChangeBucketStatus", bucket.ToString()); } } } } if (_bucketsOwnershipMap != null) { ArrayList nodeBuckets = _bucketsOwnershipMap[node] as ArrayList; if (nodeBuckets != null) { foreach (int bucketId in buckets) { int indexOfBucket = nodeBuckets.IndexOf(new HashMapBucket(null, bucketId)); if (indexOfBucket != -1) { HashMapBucket bucket = nodeBuckets[indexOfBucket] as HashMapBucket; if (node.Equals(bucket.TempAddress)) { bucket.Status = BucketStatus.UnderStateTxfr; } } } } } } } finally { Sync.ReleaseWriterLock(); } }
/// <summary> /// Adds the Current Primary cache's location identifier in the Response cookie collection. /// </summary> /// <param name="context">Context of current HttpRequest.</param> private void UpdateCookies(HttpContext context) { if (_cache != null) { if (!string.IsNullOrEmpty(_cache.PrimaryPrefix)) { context.Response.Cookies.Set(new HttpCookie(LOC_IDENTIFIER, _cache.PrimaryPrefix)); if (_logs) { NCacheLog.Info("Session Location Changed: New_Location=" + _cache.PrimaryPrefix); } } } }
/// <summary> /// Occurs when ASP.NET application is disposed /// </summary> /// <param name="o"></param> /// <param name="args"></param> private void Dispose(object o, EventArgs args) { try { if (CacheContainer.DisposeCacheInstance()) { if (NCacheLog != null) { NCacheLog.Info("NOutputCache disposed"); } } } catch (Exception e) { RaiseException(e); } }
public void LogInfo(string message, string sessionID) { try { if (sessionID == null) { sessionID = ""; } if (NCacheLog != null) { NCacheLog.Info("[Info]", sessionID + " :" + message); } } catch (Exception ex) { LogError(ex, sessionID); } }
protected DistributionMaps GetMapsOnNodeLeaving(DistributionInfoData distInfoData) { ArrayList tmpMap = null; Hashtable bucketsOwnershipMap = null; _existingMembers.Remove(distInfoData.AffectedNode.NodeAddress); if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.GetMapsOnNodeLeaving()", "Before Calling DistributeOrphanBuckets() ---- Leaving Node:" + distInfoData.AffectedNode.NodeAddress.ToString() + " Existing Members Count:0" + _existingMembers.Count); } tmpMap = DistributeHashMap.DistributeOrphanBuckets(_lastCreatedHashMap, distInfoData.AffectedNode.NodeAddress, _existingMembers); if (tmpMap == null) { return(null); } _lastCreatedHashMap = tmpMap.Clone() as ArrayList; bucketsOwnershipMap = GetBucketsOwnershipMap(_lastCreatedHashMap); return(new DistributionMaps(_lastCreatedHashMap, bucketsOwnershipMap)); }
private void InitializeCache(HttpApplication application) { this._cacheId = ConfigurationSettings.AppSettings["cacheName"]; if (this._cacheId == null || this._cacheId == string.Empty) { throw new ConfigurationException("The 'cacheName' attribute cannot be null or empty string"); } string[] boolValStrings = { "exceptionsEnabled", "writeExceptionsToEventLog", "enableLogs", "enableDetailLogs", "clearASPSession" }; string configVal = null; bool value = false; for (int i = 0; i < boolValStrings.Length; i++) { configVal = ConfigurationSettings.AppSettings[boolValStrings[i]]; if (configVal != null) { if (configVal != "true" && configVal != "false") { throw new ConfigurationException("The '" + boolValStrings[i] + "' attribute must be one of the following values: true, false."); } else { value = Convert.ToBoolean(configVal); switch (i) { case 0: this._exceptionsEnabled = value; break; case 1: this._writeExceptionsToEventLog = value; break; case 2: this._logs = value; break; case 3: this._detailedLogs = value; break; case 4: this._clearASPSession = value; break; } } } } if (this._logs || this._detailedLogs) { if (_ncacheLog == null) { _ncacheLog = new NCacheLogger(); _ncacheLog.Initialize(LoggerNames.HttpModule, this._cacheId); if (this._detailedLogs) { NCacheLog.SetLevel("all"); } else { if (this._logs) { NCacheLog.SetLevel("info"); } } } } _applicationId = ConfigurationSettings.AppSettings["sessionAppId"]; if (_isLocationAffinityEnabled) { _cache = new RegionalCache(_ncacheLog, NCacheSessionStateConfigReader.LoadSessionLocationSettings()); } else { _cache = new SingleRegionCache(); } try { this._cache.InitializeCache(this._cacheId); this._cache.ExceptionsEnabled = true; if (NCacheLog != null) { NCacheLog.Info("NSessionStateModule initialized"); } application.Application["NSessionStateModule.Cache"] = this._cache; } catch (Exception e) { RaiseExceptions(e); } }
public override Hashtable GetBucketsOwnershipMap(ArrayList hashMap) { Hashtable bucketsOwnerShipMap = new Hashtable(); try { Sync.AcquireReaderLock(Timeout.Infinite); Hashtable coordinatorNodesOwnershipMap = base.GetBucketsOwnershipMap(hashMap); Hashtable currentOwnershipMap = _bucketsOwnershipMap != null?_bucketsOwnershipMap.Clone() as Hashtable : null; ArrayList replicas = null; Address partitionCoordinator = null; if (coordinatorNodesOwnershipMap != null) { IDictionaryEnumerator ide = coordinatorNodesOwnershipMap.GetEnumerator(); while (ide.MoveNext()) { partitionCoordinator = ide.Key as Address; ArrayList coordinatorBuckets = ide.Value as ArrayList; string subgroup = _subGroupMap[partitionCoordinator] as string; if (subgroup != null) { replicas = _partitionNodesInfo[subgroup] as ArrayList; if (replicas != null) { foreach (PartNodeInfo node in replicas) { if (node.IsCoordinator) { bucketsOwnerShipMap.Add(node.NodeAddress, coordinatorBuckets); if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("PoRDistMgr.GetBucketsOwnerShipMap", subgroup + ": " + node.NodeAddress.ToString() + " has got " + coordinatorBuckets.Count + " buckets"); } } else { ArrayList currentBuckets = currentOwnershipMap != null ? currentOwnershipMap[node.NodeAddress] as ArrayList : null; ArrayList updatedBucketsList = new ArrayList(); if (currentBuckets != null) { //Node was already in the partitioned. foreach (HashMapBucket bucket in currentBuckets) { //if bucket is not transferred to the replica yet then we //change the temp address to make sure that if the coordinator //of the partitioned is changed, it is reflected in the map. if (coordinatorBuckets.Contains(bucket)) { if (bucket.TempAddress != null && !bucket.PermanentAddress.Equals(bucket.TempAddress)) { bucket.PermanentAddress = partitionCoordinator; } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("PoRDistMgr.GetBucketsOwnerShipMap", bucket.ToString() + " after coordinator left"); } updatedBucketsList.Add(bucket.Clone()); } } //during loadbalancing; some new buckets may be assigned to a replica coordinator. foreach (HashMapBucket coodinatorBucket in coordinatorBuckets) { if (!currentBuckets.Contains(coodinatorBucket)) { HashMapBucket newNodeBucket = coodinatorBucket.Clone() as HashMapBucket; newNodeBucket.PermanentAddress = partitionCoordinator; newNodeBucket.TempAddress = node.NodeAddress; //replica node need to state transfer from his coordinator. newNodeBucket.Status = BucketStatus.NeedTransfer; updatedBucketsList.Add(newNodeBucket); if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("PoRDistMgr.GetBucketsOwnerShipMap", newNodeBucket.ToString() + " new bucket assigned to replica"); } } } } else { //it is a new replica node,so we create a new bucket list for this node foreach (HashMapBucket coodinatorBucket in coordinatorBuckets) { HashMapBucket newNodeBucket = coodinatorBucket.Clone() as HashMapBucket; newNodeBucket.PermanentAddress = partitionCoordinator; newNodeBucket.TempAddress = node.NodeAddress; //replica node need to state transfer from his coordinator. newNodeBucket.Status = BucketStatus.NeedTransfer; updatedBucketsList.Add(newNodeBucket); if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("PoRDistMgr.GetBucketsOwnerShipMap", newNodeBucket.ToString() + " fresh replica"); } } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("PoRDistMgr.GetBucketsOwnerShipMap", subgroup + ": " + node.NodeAddress.ToString() + " has got " + updatedBucketsList.Count + " buckets"); } bucketsOwnerShipMap.Add(node.NodeAddress, updatedBucketsList); } } } } } } } catch (Exception e) { NCacheLog.Error("PoRDistMgr.GetBucketsOwnerShipMap", e.ToString()); } finally { Sync.ReleaseReaderLock(); } return(bucketsOwnerShipMap); }
/// <summary> /// Called by the scheduler to remove the items that has expired /// </summary> public bool Expire() { //indicates whether some items expired during this interval or not... bool expired = false; //if user has updated the file then the new values will be reloaded. _sleepInterval = ServiceConfiguration.ExpirationBulkRemoveDelay; _removeThreshhold = ServiceConfiguration.ExpirationBulkRemoveSize; //notification is sent for a max of 100k data if multiple items... //otherwise if a single item is greater than 100k then notification is sent for //that item only... int notifThreshold = 30 * 1024; CacheBase cacheInst = _context.CacheImpl; CacheBase cache = _context.CacheInternal; Cache rootCache = _context.CacheRoot; object[] keys = null; object[] values = null; if (cache == null) { throw new InvalidOperationException("No cache instance defined"); } if (_context.ReaderMgr != null) { _context.ReaderMgr.ExpireReader(CleanInterval); } bool allowExpire = AllowClusteredExpiry; //in case of replication and por, only the coordinator/sub-coordinator is responsible to expire the items. if (!allowExpire) { return(false); } ClusteredArrayList selectedKeys = new ClusteredArrayList(); ClusteredArrayList dependencyChangedSelectedKeys = new ClusteredArrayList(); int oldItemsCount = 0; HashVector oldeItems = null; try { StartLogging(); DateTime startTime = DateTime.Now; int currentTime = AppUtil.DiffSeconds(startTime); if (_context.IsDbSyncCoordinator) { _cdbSyncMgr.AcquireSyncData(); // get the modified keys. and bulk remove them all. this returns // keys from both sql and oledb providers. IDictionary dbkeys = _cdbSyncMgr.GetExpiredKeys(); if (dbkeys.Count > 0) { ClusteredArrayList expire = dbkeys["expire-items"] as ClusteredArrayList; ClusteredArrayList resync = dbkeys["resync-items"] as ClusteredArrayList; if (_context.CacheImpl == null) { return(false); } if (expire.Count > 0) { OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); operationContext.Add(OperationContextFieldName.RaiseCQNotification, true); _topLevelCache.CascadedRemove(expire, ItemRemoveReason.DependencyChanged, true, operationContext); _cdbSyncMgr.FlushSyncData(); //set the flag that item has expired from cache. expired = true; } if (resync.Count > 0 && _context.DsMgr != null) { IEnumerator e = resync.GetEnumerator(); while (e.MoveNext()) { CacheEntry oldEntry = cache.Get(e.Current, new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation)); if (oldEntry != null) { _context.DsMgr.ResyncCacheItemAsync(e.Current, oldEntry.ExpirationHint, null, oldEntry.GroupInfo, oldEntry.QueryInfo, oldEntry.ResyncProviderName); } else { _context.DsMgr.ResyncCacheItemAsync(e.Current, oldEntry.ExpirationHint, null, null, null, oldEntry.ResyncProviderName); } } } } } int cleanSize = (int)Math.Ceiling(cache.Count * _cleanRatio); //set the flag that we are going to expire the items. if (_cacheLastAccessLoggingIntervalPassed >= _cacheLastAccessLoggingInterval) { _cacheLastAccessLoggingInterval = CacheLastAccessLoggingInterval; _cacheLastAccessCountEnabled = IsCacheLastAccessCountEnabled; _cacheLastAccessCountLoggingEnabled = IsCacheLastAccessLoggingEnabled; _cacheLastAccessInterval = CacheLastAccessCountInterval; } else { _cacheLastAccessLoggingIntervalPassed++; } if (_cacheLastAccessCountEnabled && _cacheLastAccessCountLoggingEnabled) { if (_cacheLastAccessLoggingIntervalPassed >= _cacheLastAccessLoggingInterval) { _cacheLastAccessLoggingIntervalPassed = 0; oldeItems = new HashVector(); } } lock (_mainIndex.SyncRoot) { IDictionaryEnumerator em = _mainIndex.GetEnumerator(); //added by muds if (em != null) { while (em.MoveNext()) { ExpirationHint hint = em.Value as ExpirationHint; if (hint != null && _cacheLastAccessCountEnabled && hint is IdleExpiration) { IdleExpiration slidingExpHint = hint as IdleExpiration; TimeSpan diff = AppUtil.GetDateTime(AppUtil.DiffSeconds(DateTime.Now)) - AppUtil.GetDateTime(slidingExpHint.LastAccessTime); if (diff.TotalMinutes >= _cacheLastAccessInterval) { oldItemsCount++; if (oldeItems != null) { oldeItems.Add(em.Key, null); } } } if (hint == null || hint.SortKey.CompareTo(currentTime) >= 0) { continue; } if (!allowExpire && hint.IsRoutable) { continue; } if (hint.DetermineExpiration(_context)) { if (hint.NeedsReSync && _context.DsMgr != null) { //get old entry to know existing groupinfo and queryinfo for tag purposes. CacheEntry oldEntry = cache.Get(em.Key, new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation)); if (oldEntry != null) { _context.DsMgr.ResyncCacheItemAsync(em.Key, hint, null, oldEntry.GroupInfo, oldEntry.QueryInfo, oldEntry.ResyncProviderName); } else { _context.DsMgr.ResyncCacheItemAsync(em.Key, hint, null, null, null, oldEntry.ResyncProviderName); } } else { if (hint.GetExpiringHint() is FixedExpiration || hint.GetExpiringHint() is IdleExpiration) { selectedKeys.Add(em.Key); } else { dependencyChangedSelectedKeys.Add(em.Key); } } if (cleanSize > 0 && selectedKeys.Count == cleanSize) { break; } } } } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("ExpirationManager.Expire()", String.Format("Expiry time for {0}/{1} Items: " + (DateTime.UtcNow - startTime), selectedKeys.Count, /*_expiryIndex.KeyCount*/ cache.Count)); } } catch (Exception e) { NCacheLog.Error("ExpirationManager.Expire(bool)", "LocalCache(Expire): " + e.ToString()); } finally { _context.PerfStatsColl.IncrementCacheLastAccessCountStats(oldItemsCount); ApplyLoggs(); ClusteredArrayList dependentItems = new ClusteredArrayList(); ClusteredArrayList removedItems = new ClusteredArrayList(); DateTime startTime = DateTime.Now; HashVector expiredItemTable = new HashVector(); expiredItemTable.Add(ItemRemoveReason.Expired, selectedKeys); //Time based expiration expiredItemTable.Add(ItemRemoveReason.DependencyChanged, dependencyChangedSelectedKeys); //FileDependency or any other try { IDictionaryEnumerator ide = expiredItemTable.GetEnumerator(); while (ide.MoveNext()) { selectedKeys = ide.Value as ClusteredArrayList; ItemRemoveReason removedReason = (ItemRemoveReason)ide.Key; if (selectedKeys.Count > 0) { //new architectural changes begins from here. ClusteredArrayList keysTobeRemoved = new ClusteredArrayList(); for (int i = 0; i < selectedKeys.Count && !_cacheCleared; i++) { keysTobeRemoved.Add(selectedKeys[i]); if (keysTobeRemoved.Count % _removeThreshhold == 0) { try { if (this.IsDisposed) { break; } OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); operationContext.Add(OperationContextFieldName.RaiseCQNotification, true); object[][] keysExposed = keysTobeRemoved.ToInternalArray(); foreach (object[] keyCollection in keysExposed) { ArrayList removed = cache.RemoveSync(keyCollection, removedReason, false, operationContext) as ArrayList; if (removed != null) { removedItems.AddRange(removed); } } //set the flag that item has expired from cache... expired = true; if (_context.PerfStatsColl != null) { _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(keysTobeRemoved.Count); } } catch (Exception e) { NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing expired items. Error " + e.ToString()); } keysTobeRemoved.Clear(); if (removedItems != null && removedItems.Count > 0) { dependentItems.AddRange(removedItems); removedItems.Clear(); } //we stop the activity of the current thread so that normal user operation is not affected. Thread.Sleep(_sleepInterval * 1000); } } if (!this.IsDisposed && keysTobeRemoved.Count > 0) { try { OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); operationContext.Add(OperationContextFieldName.RaiseCQNotification, true); object[][] keysExposed = keysTobeRemoved.ToInternalArray(); foreach (object[] keyCollection in keysExposed) { ArrayList removed = cache.RemoveSync(keyCollection, removedReason, false, operationContext) as ArrayList; if (removed != null) { removedItems.AddRange(removed); } } //set the flag that item has expired from cache... expired = true; if (_context.PerfStatsColl != null) { _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(keysTobeRemoved.Count); } if (removedItems != null && removedItems.Count > 0) { dependentItems.AddRange(removedItems); removedItems.Clear(); } } catch (Exception e) { NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing expired items. Error " + e.ToString()); } } } } if (!this.IsDisposed && dependentItems.Count > 0) { ClusteredArrayList removableList = new ClusteredArrayList(); if (rootCache != null) { foreach (object depenentItme in dependentItems) { if (depenentItme == null) { continue; } removableList.Add(depenentItme); if (removableList.Count % 100 == 0) { try { if (this.IsDisposed) { break; } OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); operationContext.Add(OperationContextFieldName.RaiseCQNotification, true); rootCache.CascadedRemove(removableList, ItemRemoveReason.DependencyChanged, true, operationContext); if (_context.PerfStatsColl != null) { _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(removableList.Count); } } catch (Exception exc) { NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing dependent items. Error " + exc.ToString()); } removableList.Clear(); } } if (!this.IsDisposed && removableList.Count > 0) { try { OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); operationContext.Add(OperationContextFieldName.RaiseCQNotification, true); rootCache.CascadedRemove(removableList, ItemRemoveReason.DependencyChanged, true, operationContext); if (_context.PerfStatsColl != null) { _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(removableList.Count); } } catch (Exception exc) { NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing dependent items. Error " + exc.ToString()); } removableList.Clear(); } } } } finally { _transitoryIndex.Clear(); lock (this) { _cacheCleared = false; } if (oldeItems != null) { StringBuilder sb = new StringBuilder(); IDictionaryEnumerator ide = oldeItems.GetEnumerator(); int count = 1; while (ide.MoveNext()) { sb.Append(ide.Key + ", "); if (count % 10 == 0) { sb.Append("\r\n"); count = 1; } else { count++; } } NCacheLog.Info(sb.ToString().Trim()); } } } return(expired); }
/// <summary> /// Initializes a module and prepares it to handle requests. /// </summary> /// <param name="application">An <see cref="System.Web.HttpApplication"/> object that provides /// references to the intrinsic server objects (for example, /// Request, Response, Session, and Server) used to service HTTP requests. /// </param> void IHttpModule.Init(HttpApplication application) { if (application == null) { throw new ArgumentNullException("application"); } this._onResolveRequestCache = new EventHandler(ResolveRequestCache); this._onUpdaterequestCache = new EventHandler(UpdateRequestCache); this._onDispose = new EventHandler(Dispose); application.ResolveRequestCache += this._onResolveRequestCache; application.UpdateRequestCache += this._onUpdaterequestCache; application.Disposed += this._onDispose; if (_reader == null) { lock (s_mutex) { if (_reader == null) { NItem.RegisterTypeWithCompactFramework(); _reader = new OutPutCacheConfigReader(); _settings = _reader.LoadCacheSettings(); _reader.LoadPageSettings(); } } } try { if (IsNullOrEmpty(_settings.CacheName)) { return; } if (_settings.EnableLogs || _settings.EnableDetailedLogs) { _ncacheLog = new NCacheLogger(); _ncacheLog.Initialize(LoggerNames.OutputCache, _settings.CacheName); if (_settings.EnableDetailedLogs) { NCacheLog.SetLevel("all"); } else { if (_settings.EnableLogs) { NCacheLog.SetLevel("info"); } } } lock (s_mutex) { this._cache = CacheContainer.GetCacheInstance(_settings); } if (NCacheLog != null) { NCacheLog.Info("NOutputCache initialized"); } } catch (Exception e) { RaiseException(e); } }
/// <summary> /// Called by the scheduler to remove the items that has expired /// </summary> public bool Expire() { //indicates whether some items expired during this interval or not... bool expired = false; //if user has updated the file then the new values will be reloaded. _sleepInterval = ServiceConfiguration.ExpirationBulkRemoveDelay; _removeThreshhold = ServiceConfiguration.ExpirationBulkRemoveSize; CacheBase cacheInst = _context.CacheImpl; CacheBase cache = _context.CacheInternal; Cache rootCache = _context.CacheRoot; if (cache == null) { throw new InvalidOperationException("No cache instance defined"); } bool allowExpire = AllowClusteredExpiry; //in case of replication and por, only the coordinator/sub-coordinator is responsible to expire the items. if (!allowExpire) { return(false); } ClusteredArrayList selectedKeys = new ClusteredArrayList(); int oldItemsCount = 0; HashVector oldeItems = null; try { StartLogging(); DateTime startTime = DateTime.Now; int currentTime = AppUtil.DiffSeconds(startTime); int cleanSize = (int)Math.Ceiling(cache.Count * _cleanRatio); //set the flag that we are going to expire the items. if (_cacheLastAccessLoggingIntervalPassed >= _cacheLastAccessLoggingInterval) { _cacheLastAccessLoggingInterval = CacheLastAccessLoggingInterval; _cacheLastAccessCountEnabled = IsCacheLastAccessCountEnabled; _cacheLastAccessCountLoggingEnabled = IsCacheLastAccessLoggingEnabled; _cacheLastAccessInterval = CacheLastAccessCountInterval; } else { _cacheLastAccessLoggingIntervalPassed++; } if (_cacheLastAccessCountEnabled && _cacheLastAccessCountLoggingEnabled) { if (_cacheLastAccessLoggingIntervalPassed >= _cacheLastAccessLoggingInterval) { _cacheLastAccessLoggingIntervalPassed = 0; oldeItems = new HashVector(); } } lock (_mainIndex.SyncRoot) { IDictionaryEnumerator em = _mainIndex.GetEnumerator(); if (em != null) { while (em.MoveNext()) { ExpirationHint hint = em.Value as ExpirationHint; if (hint != null && _cacheLastAccessCountEnabled && hint is IdleExpiration) { IdleExpiration slidingExpHint = hint as IdleExpiration; TimeSpan diff = AppUtil.GetDateTime(AppUtil.DiffSeconds(DateTime.Now)) - AppUtil.GetDateTime(slidingExpHint.LastAccessTime); if (diff.TotalMinutes >= _cacheLastAccessInterval) { oldItemsCount++; if (oldeItems != null) { oldeItems.Add(em.Key, null); } } } if (hint == null || hint.SortKey.CompareTo(currentTime) >= 0) { continue; } if (hint.DetermineExpiration(_context)) { selectedKeys.Add(em.Key); if (cleanSize > 0 && selectedKeys.Count == cleanSize) { break; } } } } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("ExpirationManager.Expire()", String.Format("Expiry time for {0}/{1} Items: " + (DateTime.UtcNow - startTime), selectedKeys.Count, /*_expiryIndex.KeyCount*/ cache.Count)); } } catch (Exception e) { NCacheLog.Error("ExpirationManager.Expire(bool)", "LocalCache(Expire): " + e.ToString()); } finally { _context.PerfStatsColl.IncrementCacheLastAccessCountStats(oldItemsCount); ApplyLoggs(); ClusteredArrayList dependentItems = new ClusteredArrayList(); DateTime startTime = DateTime.Now; HashVector expiredItemTable = new HashVector(); expiredItemTable.Add(ItemRemoveReason.Expired, selectedKeys);//Time based expiration try { IDictionaryEnumerator ide = expiredItemTable.GetEnumerator(); while (ide.MoveNext()) { selectedKeys = ide.Value as ClusteredArrayList; ItemRemoveReason removedReason = (ItemRemoveReason)ide.Key; if (selectedKeys.Count > 0) { //new architectural changes begins from here. ClusteredArrayList keysTobeRemoved = new ClusteredArrayList(); for (int i = 0; i < selectedKeys.Count && !_cacheCleared; i++) { keysTobeRemoved.Add(selectedKeys[i]); if (keysTobeRemoved.Count % _removeThreshhold == 0) { try { if (this.IsDisposed) { break; } OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); object[][] keysExposed = keysTobeRemoved.ToInternalArray(); foreach (object[] collection in keysExposed) { cache.RemoveSync(collection, removedReason, false, operationContext); } //set the flag that item has expired from cache... expired = true; if (_context.PerfStatsColl != null) { _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(keysTobeRemoved.Count); } } catch (Exception e) { NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing expired items. Error " + e.ToString()); } keysTobeRemoved.Clear(); //we stop the activity of the current thread so that normal user operation is not affected. Thread.Sleep(_sleepInterval); } } if (!this.IsDisposed && keysTobeRemoved.Count > 0) { try { OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation); object[][] keysExposed = keysTobeRemoved.ToInternalArray(); foreach (object[] keyCollection in keysExposed) { cache.RemoveSync(keyCollection, removedReason, false, operationContext); } //set the flag that item has expired from cache... expired = true; if (_context.PerfStatsColl != null) { _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(keysTobeRemoved.Count); } } catch (Exception e) { NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing expired items. Error " + e.ToString()); } } } } } finally { _transitoryIndex.Clear(); lock (this) { _cacheCleared = false; } if (oldeItems != null) { StringBuilder sb = new StringBuilder(); IDictionaryEnumerator ide = oldeItems.GetEnumerator(); int count = 1; while (ide.MoveNext()) { sb.Append(ide.Key + ", "); if (count % 10 == 0) { sb.Append("\r\n"); count = 1; } else { count++; } } NCacheLog.Info(sb.ToString().Trim()); } } } return(expired); }
public override DistributionMaps GetMaps(DistributionInfoData distInfoData) { ArrayList tmpMap = null; Hashtable bucketsOwnershipMap = null; ArrayList partitionNodes = new ArrayList(); if (_installedHashMap == null) { tmpMap = new ArrayList(TotalBuckets); for (int i = 0; i < TotalBuckets; i++) { HashMapBucket bucket = new HashMapBucket(distInfoData.AffectedNode.NodeAddress, i, BucketStatus.Functional); tmpMap.Add(bucket); } _existingMembers.Add(distInfoData.AffectedNode.NodeAddress); _subGroupMap[distInfoData.AffectedNode.NodeAddress] = distInfoData.AffectedNode.SubGroup; //for each new group we are keeping list of members. For only Partition it will be one ..for POR can be greater then one. //This is new member, the first one. So create the list here. distInfoData.AffectedNode.IsCoordinator = true; partitionNodes.Add(distInfoData.AffectedNode); _partitionNodesInfo.Add(distInfoData.AffectedNode.SubGroup, partitionNodes); //A hash table keeping list of addresses against each GROUP/Partition. _lastCreatedHashMap = tmpMap.Clone() as ArrayList; bucketsOwnershipMap = GetBucketsOwnershipMap(_lastCreatedHashMap); return(new DistributionMaps(_lastCreatedHashMap, bucketsOwnershipMap)); } //for non-coordinator node that recently becomes coordinator... else if (_lastCreatedHashMap == null) { _lastCreatedHashMap = _installedHashMap.Clone() as ArrayList; } switch (distInfoData.ClustActivity) { case ClusterActivity.NodeJoin: try { //assuming existing members doesnot contain the newly added member. if (!_partitionNodesInfo.ContainsKey(distInfoData.AffectedNode.SubGroup)) { partitionNodes = new ArrayList(); distInfoData.AffectedNode.IsCoordinator = true; partitionNodes.Add(distInfoData.AffectedNode); _subGroupMap[distInfoData.AffectedNode.NodeAddress] = distInfoData.AffectedNode.SubGroup; _partitionNodesInfo.Add(distInfoData.AffectedNode.SubGroup, partitionNodes); //A hash table keeping list of addresses against each GROUP/Partition. if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionMgr.GetMaps()", "Sending new map as a new node joined the cluster"); } return(GetMapsOnNodeJoining(distInfoData)); } else { partitionNodes = (ArrayList)_partitionNodesInfo[distInfoData.AffectedNode.SubGroup]; partitionNodes.Add(distInfoData.AffectedNode); _subGroupMap[distInfoData.AffectedNode.NodeAddress] = distInfoData.AffectedNode.SubGroup; return(new DistributionMaps(_lastCreatedHashMap, GetBucketsOwnershipMap(_lastCreatedHashMap))); } } catch (Exception e) { if (NCacheLog.IsErrorEnabled) { NCacheLog.Error("DistributionMgr.GetMaps()", e.ToString()); } break; } case ClusterActivity.NodeLeave: //assuming existing members do not containt the node to be removed/left. _existingMembers.Remove(distInfoData.AffectedNode.NodeAddress); _subGroupMap.Remove(distInfoData.AffectedNode.NodeAddress); //Check if this node is the only one in partition or not.So better do distribution if (IsLastNodeInPartition(distInfoData.AffectedNode)) { _partitionNodesInfo.Remove(distInfoData.AffectedNode.SubGroup); return(GetMapsOnNodeLeaving(distInfoData)); } else //this mean we still have nodes available for this partition. { ArrayList groupNodes = (ArrayList)_partitionNodesInfo[distInfoData.AffectedNode.SubGroup]; if (IsCoordinatorNodeInPartition(distInfoData.AffectedNode)) { groupNodes.Remove((object)distInfoData.AffectedNode); ((PartNodeInfo)groupNodes[0]).IsCoordinator = true; _partitionNodesInfo[distInfoData.AffectedNode.SubGroup] = groupNodes; _existingMembers.Add(((PartNodeInfo)groupNodes[0]).NodeAddress); tmpMap = UpgradeToCoordinatorOfReplica(distInfoData.AffectedNode.NodeAddress, ((PartNodeInfo)groupNodes[0]).NodeAddress); _lastCreatedHashMap = tmpMap.Clone() as ArrayList; bucketsOwnershipMap = GetBucketsOwnershipMap(_lastCreatedHashMap); return(new DistributionMaps(_lastCreatedHashMap, bucketsOwnershipMap)); } else { //simply remove the node and get a new bucket ownership map. groupNodes.Remove(distInfoData.AffectedNode); return(new DistributionMaps(_lastCreatedHashMap, GetBucketsOwnershipMap(_lastCreatedHashMap))); } } case ClusterActivity.None: BalanceNodeMgr bnMgr = new BalanceNodeMgr(null); DistributionMaps result = bnMgr.BalanceNodes(distInfoData, _lastCreatedHashMap, _bucketsStats, _existingMembers); if (result.Hashmap != null) { _lastCreatedHashMap = result.Hashmap.Clone() as ArrayList; result.BucketsOwnershipMap = GetBucketsOwnershipMap(_lastCreatedHashMap); } return(result); default: break; } return(null); }