/// <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(); } }
/// <summary> /// Provides implementation of Remove method of the ICacheStorage interface. /// Removes an object from the store, specified by the passed in key /// </summary> /// <param name="key">key</param> /// <returns>object</returns> public override object Remove(object key) { Sync.AcquireWriterLock(Timeout.Infinite); try { return(_storage.Remove(key)); } finally { Sync.ReleaseWriterLock(); } }
/// <summary> /// Provides implementation of Insert method of the ICacheStorage interface. /// Insert/Add the key value pair to the store. /// </summary> /// <param name="key">key</param> /// <param name="item">object</param> /// <returns>returns the result of operation.</returns> public override StoreInsResult Insert(object key, object item, Boolean allowExtendedSize) { Sync.AcquireWriterLock(Timeout.Infinite); try { return(_storage.Insert(key, item, allowExtendedSize)); } finally { Sync.ReleaseWriterLock(); } }
/// <summary> /// Removes all entries from the store. /// </summary> public override void Clear() { Sync.AcquireWriterLock(Timeout.Infinite); try { _storage.Clear(); } finally { Sync.ReleaseWriterLock(); } }
/// <summary> /// Provides implementation of Add method of the ICacheStorage interface. /// Add the key value pair to the store. /// </summary> /// <param name="key">key</param> /// <param name="item">object</param> /// <returns>returns the result of operation.</returns> public override StoreAddResult Add(object key, IStorageEntry item, Boolean allowExtendedSize) { Sync.AcquireWriterLock(Timeout.Infinite); try { return(_storage.Add(key, item, allowExtendedSize)); } finally { Sync.ReleaseWriterLock(); } }
/// <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> /// Releases a bucket by setting its status again to functional. Only /// node who has set its status to state trxfr can change its status. /// </summary> /// <param name="buckets"></param> /// <param name="node"></param> public void ReleaseBuckets(ArrayList buckets, Address requestingNode) { try { 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)) { bucket.Status = BucketStatus.Functional; //Change permnant address only when node who locked the bucket //has sent request to release after he has transfered the bucket completely. bucket.PermanentAddress = bucket.TempAddress; } //NCacheLog.Error("DistributionMgr.ReleaseBuckets", " Released bucket from InstalledHashMap " + bucket.ToString() + ". Requested by " + requestingNode); } } } if (_bucketsOwnershipMap != null) { ArrayList nodeBuckets = _bucketsOwnershipMap[requestingNode] as ArrayList; if (nodeBuckets != null) { foreach (int bucketId in buckets) { int indexOfBucket = -1; int startIndex = 0; do { //TempFix: Updates status for multipile occurances of the same bucket in ownership map for replica. indexOfBucket = nodeBuckets.IndexOf(new HashMapBucket(null, bucketId), startIndex); if (indexOfBucket != -1) { HashMapBucket bucket = nodeBuckets[indexOfBucket] as HashMapBucket; if (requestingNode.Equals(bucket.TempAddress)) { bucket.Status = BucketStatus.Functional; //Change permnant address only when node who locked the bucket //has sent request to release after he has transfered the bucket completely. bucket.PermanentAddress = requestingNode; } startIndex = indexOfBucket + 1; } } while (indexOfBucket >= 0); } } } } finally { Sync.ReleaseWriterLock(); NotifyBucketUpdate(); } } catch (NullReferenceException e) { //Null is expected at start of cache } catch (Exception e) { NCacheLog.Error("DistributionMgr.ReleaseBuckets", e.ToString()); } }