/// <summary> /// Retrieve a List of <see cref="string"/> of all available key's on specific server node. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns> /// the status if communication where sucessfully or if it failed. /// </returns> internal static List <string> GetAllKeys(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log using (var msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.GetAllKeys)) { if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } if (!ClientContext) { msg.ClientContext = false; msg.Status = IndexusMessage.StatusValue.ReplicationRequest; } HandleProtocol(msg, string.Empty); return(msg.Payload != null?Formatters.Serialization.BinaryDeSerialize <List <string> >(msg.Payload) : new List <string>()); } }
/// <summary> /// Replicates the specified MSG. /// </summary> /// <param name="msg">The MSG.</param> public void Replicate(COM.IndexusMessage msg) { #region Access Log #if TRACE { COM.Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log try { lock (bulkObject) { this.replicationQueue.Enqueue(msg); } if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { COM.Handler.LogHandler.SyncInfo( string.Format(COM.Constants.SYNCENQUEUELOG, msg.Id, msg.Action, msg.Status ) ); } } catch (Exception ex) { Console.WriteLine(ex.Message); COM.Handler.LogHandler.Error(ex); } }
/// <summary> /// Receive statistics from server node based on provided host. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns>an object of type <see cref="IndexusStatistic"/></returns> internal static IndexusStatistic Statistic(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterStatistic); var result = new IndexusStatistic(); var msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.Statistic); if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } if (HandleProtocol(msg, string.Empty)) { var serverNodeStatistic = Formatters.Serialization.BinaryDeSerialize <IndexusStatistic>(msg.Payload); result.ServiceTotalSize = serverNodeStatistic.ServiceTotalSize; result.ServiceAmountOfObjects = serverNodeStatistic.ServiceAmountOfObjects; result.ServiceUsageList = serverNodeStatistic.ServiceUsageList; result.ApiCounterAdd = counterAdd; result.ApiCounterGet = counterGet; result.ApiCounterRemove = counterRemove; result.ApiCounterStatistic = counterStatistic; result.ApiCounterSuccess = counterSuccess; result.ApiCounterFailed = counterFailed; result.ApiHitSuccess = counterHitSuccess; result.ApiHitFailed = counterHitFailed; result.ApiCounterFailedNodeNotAvailable = counterFailedNodeNotAvailable; } else { return(new IndexusStatistic( counterAdd, counterGet, counterRemove, counterStatistic, -1, -1, -1, -1 )); } return(result); }
/// <summary> /// Removes the specified MSG. /// </summary> /// <param name="msg">The protocol message as <see cref="IndexusMessage"/> object.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Remove(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterRemove); return(HandleProtocol(msg, string.Empty)); }
/// <summary> /// Gets the specified MSG. /// </summary> /// <param name="msg">The protocol message as <see cref="IndexusMessage"/> object.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Get(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterGet); if (!ClientContext) { msg.ClientContext = false; msg.Status = IndexusMessage.StatusValue.ReplicationRequest; } if (HandleProtocol(msg, string.Empty)) { if (msg.Payload != null) { Interlocked.Increment(ref counterHitSuccess); } else { Interlocked.Increment(ref counterHitFailed); } // handling compression if (compressionEnabled) { if (compressionMinSize > -1 && Formatters.Compression.CheckHeader(msg.Payload)) { msg.Payload = Formatters.Compression.Decompress(msg.Payload); } } return(true); } else { Interlocked.Increment(ref counterHitFailed); if (!ClientContext) { return(false); } return(true); } }
/// <summary> /// Clear cache on provided server node. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Clear(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log using (var msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.RemoveAll)) { if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } return(HandleProtocol(msg, string.Empty)); } }
/// <summary> /// Updates the specified msg or its updating the available record if its already added. /// </summary> /// <param name="msg">The MSG.</param> public void Update(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log lock (BulkObject) { Cleanup c; if (this.CleanupDict.ContainsKey(msg.Key)) { c = this.CleanupDict[msg.Key]; // update if (msg.Payload != null) { c.ObjectSize = msg.Payload.Length == 1 ? c.ObjectSize : msg.Payload.Length; } else { c.ObjectSize = 0; } c.Prio = msg.ItemPriority; c.HitRatio += 1; c.HybridPoint = CalculateHybridChecksum(c, this.CleanupCacheConfiguration); c.Span = msg.Expires.Subtract(DateTime.Now); c.UsageDatetime = DateTime.Now; } else { // add // object is not available, create a new instance / calculations / and add it to the list. var cleanup = new Cleanup(msg.Key, msg.ItemPriority, msg.Expires.Subtract(DateTime.Now), 0, DateTime.Now, msg.Payload != null ? msg.Payload.Length : 0, 0); cleanup.HybridPoint = CalculateHybridChecksum(cleanup, this.CleanupCacheConfiguration); this.CleanupDict[msg.Key] = cleanup; } } }
/// <summary> /// Adding an item to cache. /// </summary> /// <param name="msg">The protocol message as <see cref="IndexusMessage"/> object.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Add(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterAdd); // handling compression if (compressionEnabled) { if (compressionMinSize > -1 && msg.Payload != null && msg.Payload.Length >= compressionMinSize) { msg.Payload = Formatters.Compression.Compress(msg.Payload); } } return(HandleProtocol(msg, string.Empty)); }
/// <summary> /// Copies the specified MSG. /// </summary> /// <param name="msg">The MSG.</param> private void Copy(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log if (msg == null) { this.action = ActionValue.Error; throw new ArgumentNullException("IndexusMessage cannot be NULL"); } this.itemPriority = msg.ItemPriority; this.id = msg.id; this.action = msg.action; this.key = msg.key; this.payload = msg.payload; this.expires = msg.expires; this.status = msg.status; this.timestamp = msg.timestamp; }
/// <summary> /// Pings the specified server node based on provided host. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Ping(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log using (IndexusMessage msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.Ping)) { if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } if (!ClientContext) { msg.ClientContext = false; msg.Status = IndexusMessage.StatusValue.ReplicationRequest; } return(HandleProtocol(msg, string.Empty)); } }
/// <summary> /// Receive statistics from server node based on provided host. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns>an object of type <see cref="IndexusStatistic"/></returns> internal static IndexusStatistic Statistic(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterStatistic); IndexusStatistic result = new IndexusStatistic(); IndexusMessage msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.Statistic); if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } if (HandleProtocol(msg, string.Empty)) { IndexusStatistic serverNodeStatistic = Formatters.Serialization.BinaryDeSerialize<IndexusStatistic>(msg.Payload); result.ServiceTotalSize = serverNodeStatistic.ServiceTotalSize; result.ServiceAmountOfObjects = serverNodeStatistic.ServiceAmountOfObjects; result.ServiceUsageList = serverNodeStatistic.ServiceUsageList; result.apiCounterAdd = counterAdd; result.apiCounterGet = counterGet; result.apiCounterRemove = counterRemove; result.apiCounterStatistic = counterStatistic; result.apiCounterSuccess = counterSuccess; result.apiCounterFailed = counterFailed; result.apiHitSuccess = counterHitSuccess; result.apiHitFailed = counterHitFailed; result.apiCounterFailedNodeNotAvailable = counterFailedNodeNotAvailable; } else { return new IndexusStatistic( counterAdd, counterGet, counterRemove, counterStatistic, -1, -1, -1, -1 ); } return result; }
/// <summary> /// Distributes the specified to other server nodes. /// </summary> /// <param name="msg">The MSG <see cref="IndexusMessage"/></param> public override void Distribute(IndexusMessage msg) { #region Access Log #if TRACE { COM.Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log // very important because if this is not set explizit to // server mode it will try to access wrong configuration providers msg.ClientContext = false; switch (msg.Action) { case IndexusMessage.ActionValue.Add: COM.CacheUtil.Add(msg); break; case IndexusMessage.ActionValue.Remove: COM.CacheUtil.Remove(msg); break; case IndexusMessage.ActionValue.Get: case IndexusMessage.ActionValue.GetAllKeys: case IndexusMessage.ActionValue.Statistic: case IndexusMessage.ActionValue.Error: case IndexusMessage.ActionValue.Successful: case IndexusMessage.ActionValue.Ping: case IndexusMessage.ActionValue.RemoveAll: case IndexusMessage.ActionValue.MultiAdd: case IndexusMessage.ActionValue.MultiDelete: case IndexusMessage.ActionValue.MultiGet: default: Handler.LogHandler.Fatal(string.Format("Distribute option '{0}' is not supported!!", msg.Action)); #if DEBUG Console.WriteLine("Distribute option '{0}' is not supported!!", msg.Action); #endif break; } }
public override IDictionary<string, byte[]> MultiGet(List<string> keys, string host) { Dictionary<string, byte[]> result = new Dictionary<string, byte[]>(); using (IndexusMessage msg = new IndexusMessage()) { msg.Hostname = host; msg.Key = "MultiGetKeyServerNode2ServerNode"; msg.Action = IndexusMessage.ActionValue.MultiGet; msg.Payload = Formatters.Serialization.BinarySerialize(keys); if (CacheUtil.Get(msg) && msg.Payload != null) { IDictionary<string, byte[]> partialResult = Formatters.Serialization.BinaryDeSerialize<IDictionary<string, byte[]>>(msg.Payload); foreach (KeyValuePair<string, byte[]> item in partialResult) { result.Add(item.Key, item.Value); } } } return result; }
/// <summary> /// Handles the client message. /// </summary> /// <param name="state">The state.</param> private void HandleClientMessage(COM.Sockets.SharedCacheStateObject state) { #region Access Log #if TRACE { COM.Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log if (state != null) { COM.IndexusMessage msg = null; try { System.IO.MemoryStream stream = new System.IO.MemoryStream(state.DataBigBuffer); stream.Seek(0, 0); msg = new COM.IndexusMessage(stream); } catch (Exception ex) { #region Error Handling COM.Handler.LogHandler.Fatal(string.Format("[{0}] Could not create IndexusMessage from received data", state.WorkSocket.RemoteEndPoint.ToString()), ex); COM.Handler.LogHandler.Error(string.Format("[{0}] Could not create IndexusMessage from received data", state.WorkSocket.RemoteEndPoint.ToString()), ex); COM.Handler.LogHandler.Traffic(string.Format("[{0}] Could not create IndexusMessage from received data", state.WorkSocket.RemoteEndPoint.ToString())); Console.WriteLine(string.Format("[{0}] Could not create IndexusMessage from received data", state.WorkSocket.RemoteEndPoint.ToString())); using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException("Could not convert MemoryStream to indeXusMessage", msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } return; #endregion Error Handling } if (msg != null) { // check status first [Request || Response] switch (msg.Status) { case COM.IndexusMessage.StatusValue.Request: case COM.IndexusMessage.StatusValue.ReplicationRequest: { try { #region Logging #if DEBUG if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { // Add request to log COM.Handler.LogHandler.Traffic( string.Format(COM.Constants.TRAFFICLOG, state.WorkSocket.RemoteEndPoint, System.Threading.Thread.CurrentThread.ManagedThreadId, msg.Id, msg.Action.ToString(), msg.Status.ToString(), state.DataBigBuffer.LongLength ) ); } #else if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { // Add request to log COM.Handler.LogHandler.Traffic( string.Format(COM.Constants.TRAFFICLOG, state.WorkSocket.RemoteEndPoint, System.Threading.Thread.CurrentThread.ManagedThreadId, msg.Id, msg.Action.ToString(), msg.Status.ToString(), state.DataBigBuffer.LongLength ) ); } #endif #endregion #region request case COM.IndexusMessage replicationMessage = null; // if replication Request arrives as status value a different server node is the holder of this object if (ServiceLogic.NetworkDistribution.ReplicationEnabled && msg.Status != COM.IndexusMessage.StatusValue.ReplicationRequest) { // create a new object of received msg. to broadcast on servers. replicationMessage = new SharedCache.WinServiceCommon.IndexusMessage(); replicationMessage.Action = msg.Action; replicationMessage.Status = COM.IndexusMessage.StatusValue.ReplicationRequest; replicationMessage.Key = msg.Key; replicationMessage.Payload = msg.Payload; } // switch over cache actions switch (msg.Action) { case SharedCache.WinServiceCommon.IndexusMessage.ActionValue.VersionNumberSharedCache: { #region VersionNumberSharedCache msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Payload = COM.Formatters.Serialization.BinarySerialize( new AssemblyInfo().Version ); this.SendResponse(state, msg); break; #endregion VersionNumberSharedCache } case COM.IndexusMessage.ActionValue.VersionNumberClr: { #region VersionNumberClr msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Payload = COM.Formatters.Serialization.BinarySerialize(Environment.Version.ToString()); this.SendResponse(state, msg); break; #endregion VersionNumberClr } case COM.IndexusMessage.ActionValue.Ping: { #region Ping msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Payload = null; this.SendResponse(state, msg); break; #endregion Ping } case COM.IndexusMessage.ActionValue.Add: { #region Add Case try { #if DEBUG if (writeStats) { Console.WriteLine(@"Adding new Item with Key: {0}", msg.Key); } #endif LocalCache.Add(msg.Key, msg.Payload); // if the given msg expires is not MaxValue // it will be listed sub-process which clean // up in iterations the cache. // QuickFix if (msg.Expires != DateTime.MaxValue) { if (this.expire != null) { this.expire.Expire.DumpCacheItemAt(msg.Key, msg.Expires); } } // update cleanup list with new object CacheCleanup.Update(msg); msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Payload = null; msg.Status = COM.IndexusMessage.StatusValue.Response; // send object back throug the connection this.SendResponse(state, msg); #region rschuetz: MODIFIED: 21-07-2007: distribute object over wire to other installations // Question is if the client needs to wait until this happens, // or should the client first get an answer and just then it // will distribute it. if (ServiceLogic.NetworkDistribution.ReplicationEnabled && msg.Status != COM.IndexusMessage.StatusValue.ReplicationRequest) { ServiceLogic.NetworkDistribution.Replicate(replicationMessage); } #endregion } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } finally { // handle max size and purge issues if (this.cacheAmountOfObjects != -1 && this.cacheAmountOfObjects <= LocalCache.CalculatedCacheSize && !CacheCleanup.PurgeIsRunning) { #if DEBUG if (writeStats) { Console.WriteLine(@"Current Size of Cache: {0} ; {1} ", LocalCache.CalculatedCacheSize, LocalCache.CalculatedCacheSize <= 0 ? 0 : LocalCache.CalculatedCacheSize / (1024 * 1024)); } #endif List<string> remove = CacheCleanup.Purge(LocalCache.CalculatedCacheSize); if (remove != null) { lock (bulkObject) { foreach (string s in remove) { LocalCache.Remove(s); } } } } } break; #endregion Add Case } case COM.IndexusMessage.ActionValue.ExtendTtl: { #region Extend Time To Live // workitem: http://www.codeplex.com/SharedCache/WorkItem/View.aspx?WorkItemId=6129 try { #if DEBUG if (writeStats) { Console.WriteLine("Search for Object with Key: {0}, Current Cache Size: {1}", msg.Key, LocalCache.Amount()); } #endif CacheCleanup.Update(msg); this.expire.Expire.DumpCacheItemAt(msg.Key, msg.Expires); msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = null; this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion Extend Time To Live } case COM.IndexusMessage.ActionValue.Get: { #region Receive object from cache byte[] objectFromCache = new byte[1] { 0 }; try { #if DEBUG if (writeStats) { Console.WriteLine("Search for Object with Key: {0}, Current Cache Size: {1}", msg.Key, LocalCache.Amount()); } #endif objectFromCache = LocalCache.Get(msg.Key); // send new object back to client within same socket which contains the cache object. msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Payload = objectFromCache; // update cleanup list CacheCleanup.Update(msg); // bugfix: http://www.codeplex.com/WorkItem/View.aspx?ProjectName=SharedCache&WorkItemId=6167 // return null if item is already expried if (this.expire.Expire.CheckExpired(msg.Key)) { this.expire.Expire.Remove(msg.Key); LocalCache.Remove(msg.Key); CacheCleanup.Remove(msg.Key); #if DEBUG if (writeStats) { Console.WriteLine("Cleared Object with Key: {0}, Current Cache Size: {1}", msg.Key, LocalCache.Amount()); } #endif if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { COM.Handler.LogHandler.Info(string.Format("Item with Key:'{0}' has been removed and Server node {1} return NULL", msg.Key, Environment.MachineName)); } msg.Payload = null; } this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion } case COM.IndexusMessage.ActionValue.Remove: { #region Remove Case try { #if DEBUG if (writeStats) { Console.WriteLine("Remove Object with Key: {0}, current Cache amount: {1}", msg.Key, LocalCache.Amount()); } #endif // remove it from the cache. LocalCache.Remove(msg.Key); if (this.expire != null) { // remove it from the cache expiry job. this.expire.Expire.Remove(msg.Key); } // update cleanup list CacheCleanup.Remove(msg.Key); #region rschuetz: MODIFIED: 21-07-2007: distribute object over wire to other installations // Question is if the client needs to wait until this happens, // or should the client first get an answer and just then it // will distribute it. if (ServiceLogic.NetworkDistribution.ReplicationEnabled && msg.Status != COM.IndexusMessage.StatusValue.ReplicationRequest) { ServiceLogic.NetworkDistribution.Replicate(replicationMessage); } #endregion msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = null; this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion Remove Case } case COM.IndexusMessage.ActionValue.RegexGet: { #region Receiving data based on regular expression pattern try { #region #if DEBUG if (writeStats) { Console.WriteLine(@"RegexGet Operation"); } #endif #endregion IDictionary<string, byte[]> result = new Dictionary<string, byte[]>(); string regularExpressionPattern = Encoding.UTF8.GetString(msg.Payload); Regex regex = new Regex(regularExpressionPattern, RegexOptions.CultureInvariant); List<string> actualData = LocalCache.GetAllKeys(); foreach (string n in actualData) { if (regex.IsMatch(n)) { result.Add(n, LocalCache.Get(n)); } } msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = COM.Formatters.Serialization.BinarySerialize(result); this.SendResponse(state, msg); } catch (Exception ex) { #region Exception Handling using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } #endregion Exception Handling } break; #endregion Receiving data based on regular expression pattern } case COM.IndexusMessage.ActionValue.RegexRemove: { #region Regex Remove try { Regex regex = new Regex(Encoding.UTF8.GetString(msg.Payload), RegexOptions.CultureInvariant); #region local logging #if DEBUG if (writeStats) { Console.WriteLine("Regex Remove Keys which match pattern: {0}", regex.ToString()); } #endif #endregion local logging List<string> keysToRemove = new List<string>(); List<string> actualData = LocalCache.GetAllKeys(); foreach (string n in actualData) { if (regex.IsMatch(n)) keysToRemove.Add(n); } foreach (string key in keysToRemove) { // remove it from the cache. LocalCache.Remove(key); if (this.expire != null) { // remove it from the cache expiry job. this.expire.Expire.Remove(key); } // update cleanup list CacheCleanup.Remove(key); } #region rschuetz: MODIFIED: 21-07-2007: distribute object over wire to other installations // Question is if the client needs to wait until this happens, // or should the client first get an answer and just then it // will distribute it. if (ServiceLogic.NetworkDistribution.ReplicationEnabled && msg.Status != COM.IndexusMessage.StatusValue.ReplicationRequest) { ServiceLogic.NetworkDistribution.Replicate(replicationMessage); } #endregion msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = null; this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion Regex Remove } case COM.IndexusMessage.ActionValue.RemoveAll: { #region Clear all cache items! try { #if DEBUG if (writeStats) { Console.WriteLine("Clear all cache items!"); } #endif lock (bulkObject) { // remove all items from cache LocalCache.Clear(); if (this.expire != null) { // remove all items from the cache expiry job. this.expire.Expire.Clear(); } // remove all items from cleanup CacheCleanup.Clear(); } msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = null; this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion } case COM.IndexusMessage.ActionValue.GetAllKeys: { #region Get All Keys try { #if DEBUG if (writeStats) { Console.WriteLine("Get All available Key's!"); } #endif List<string> keys = LocalCache.GetAllKeys(); msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = COM.Formatters.Serialization.BinarySerialize(keys); this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion } case COM.IndexusMessage.ActionValue.Statistic: { #region Statistic try { #if DEBUG if (writeStats) { Console.WriteLine("Message Action: {0}", msg.Action.ToString()); } #endif COM.IndexusStatistic stats; // previous clients are sending a stats object, newer clients are // sending nothing to reduce interaction on the wire. if (msg.Payload != null) stats = COM.Formatters.Serialization.BinaryDeSerialize<COM.IndexusStatistic>(msg.Payload); else stats = new COM.IndexusStatistic(); // receive cache attributes and add them to cache object stats.ServiceAmountOfObjects = LocalCache.Amount(); stats.ServiceTotalSize = LocalCache.Size(); stats.ServiceUsageList = CacheCleanup.GetAccessStatList(); // adding results to return message and set all needed attributes. msg.Payload = COM.Formatters.Serialization.BinarySerialize(stats); msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion } case COM.IndexusMessage.ActionValue.GetAbsoluteTimeExpiration: { // As requested: http://www.codeplex.com/SharedCache/WorkItem/View.aspx?WorkItemId=6170 #region Collecting absolut expiration DateTime for provided keys try { #if DEBUG if (writeStats) { Console.WriteLine(@"GetAbsoluteTimeExpiration Operation: {0}", msg.Key); } #endif IDictionary<string, DateTime> result = new Dictionary<string, DateTime>(); List<string> requstedData = COM.Formatters.Serialization.BinaryDeSerialize<List<string>>(msg.Payload); if (requstedData != null) { foreach (string key in requstedData) { bool addItem = true; if (this.expire.Expire.CheckExpired(key)) { result.Add(key, DateTime.MinValue); } else { result.Add(key, this.expire.Expire.GetExpireDateTime(key)); } } msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = COM.Formatters.Serialization.BinarySerialize(result); this.SendResponse(state, msg); } else { throw new Exception("Payload could not be deserialized into a list of strings!"); } } catch (Exception ex) { #region Exception Handling using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } #endregion Exception Handling } break; #endregion Collecting absolut expiration DateTime for provided keys } case COM.IndexusMessage.ActionValue.MultiGet: { #region Receiving a list of single items from the cache try { #if DEBUG if (writeStats) { Console.WriteLine(@"MultiGet Operation: {0}", msg.Key); } #endif IDictionary<string, byte[]> result = new Dictionary<string, byte[]>(); List<string> requstedData = COM.Formatters.Serialization.BinaryDeSerialize<List<string>>(msg.Payload); if (requstedData != null) { foreach (string key in requstedData) { bool addItem = true; // bugfix: http://www.codeplex.com/WorkItem/View.aspx?ProjectName=SharedCache&WorkItemId=6167 // return null if item is already expried if (this.expire.Expire.CheckExpired(key)) { this.expire.Expire.Remove(key); LocalCache.Remove(key); CacheCleanup.Remove(key); #if DEBUG if (writeStats) { Console.WriteLine("Cleared Object with Key: {0}, Current Cache Size: {1}", msg.Key, LocalCache.Amount()); } #endif if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { COM.Handler.LogHandler.Info(string.Format("Item with Key:'{0}' has been removed and Server node {1} return NULL", msg.Key, Environment.MachineName)); } addItem = false; } if (addItem) { result.Add(key, LocalCache.Get(key)); } } msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = COM.Formatters.Serialization.BinarySerialize(result); this.SendResponse(state, msg); } else { throw new Exception("Payload could not be deserialized into a list of strings!"); } } catch (Exception ex) { #region Exception Handling using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } #endregion Exception Handling } break; #endregion Receiving a list of single items from the cache } case COM.IndexusMessage.ActionValue.MultiAdd: { #region Adding a bunch of data try { #region Stats #if DEBUG if (writeStats) { Console.WriteLine(@"Adding a bunch of data - MultiAdd"); } #endif #endregion Stats IDictionary<string, byte[]> data = COM.Formatters.Serialization.BinaryDeSerialize<IDictionary<string, byte[]>>(msg.Payload); foreach (KeyValuePair<string, byte[]> item in data) { LocalCache.Add(item.Key, item.Value); // if the given msg expires is not MaxValue // it will be listed sub-process which clean // up in iterations the cache. // QuickFix if (msg.Expires != DateTime.MaxValue) { if (this.expire != null) { this.expire.Expire.DumpCacheItemAt(item.Key, msg.Expires); } } using (COM.IndexusMessage multiMsg = new COM.IndexusMessage( COM.Handler.Unique.NextUniqueId(), msg.Status, msg.Action, msg.ItemPriority, msg.Hostname, msg.Expires, item.Key, item.Value ) ) { // update cleanup list with new object CacheCleanup.Update(multiMsg); } } msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Payload = null; msg.Status = COM.IndexusMessage.StatusValue.Response; // send object back throug the connection this.SendResponse(state, msg); #region rschuetz: MODIFIED: 21-07-2007: distribute object over wire to other installations // Question is if the client needs to wait until this happens, // or should the client first get an answer and just then it // will distribute it. if (ServiceLogic.NetworkDistribution.ReplicationEnabled && msg.Status != COM.IndexusMessage.StatusValue.ReplicationRequest) { ServiceLogic.NetworkDistribution.Replicate(replicationMessage); } #endregion } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } finally { // handle max size and purge issues if (this.cacheAmountOfObjects != -1 && this.cacheAmountOfObjects <= LocalCache.CalculatedCacheSize && !CacheCleanup.PurgeIsRunning) { #if DEBUG if (writeStats) { Console.WriteLine(@"Current Size of Cache: {0} ; {1} ", LocalCache.CalculatedCacheSize, LocalCache.CalculatedCacheSize <= 0 ? 0 : LocalCache.CalculatedCacheSize / (1024 * 1024)); } #endif List<string> remove = CacheCleanup.Purge(LocalCache.CalculatedCacheSize); if (remove != null) { lock (bulkObject) { foreach (string s in remove) { LocalCache.Remove(s); } } } } } break; #endregion Adding a bunch of data } case COM.IndexusMessage.ActionValue.MultiDelete: { #region Remove a bunch of data try { #region Stats #if DEBUG if (writeStats) { Console.WriteLine("MultiDelete Object with Key: {0}, current Cache amount: {1}", msg.Key, LocalCache.Amount()); } #endif #endregion Stats List<string> requstedDataToDelete = COM.Formatters.Serialization.BinaryDeSerialize<List<string>>(msg.Payload); foreach (string key in requstedDataToDelete) { // remove it from the cache. LocalCache.Remove(key); if (this.expire != null) { // remove it from the cache expiry job. this.expire.Expire.Remove(key); } // update cleanup list CacheCleanup.Remove(key); } msg.Action = COM.IndexusMessage.ActionValue.Successful; msg.Status = COM.IndexusMessage.StatusValue.Response; msg.Payload = null; this.SendResponse(state, msg); } catch (Exception ex) { using (COM.IndexusMessage resultMsg = new COM.IndexusMessage()) { resultMsg.Action = COM.IndexusMessage.ActionValue.Error; resultMsg.Status = COM.IndexusMessage.StatusValue.Response; resultMsg.Payload = COM.Formatters.Serialization.BinarySerialize( new COM.CacheException(msg.Action.ToString(), msg.Action, msg.Status, ex) ); this.SendResponse(state, resultMsg); } } break; #endregion Remove a bunch of data } } break; #endregion request case } finally { // msg is not needed anymore and since its implmente IDisposable it can be disposed at this place if (msg != null) { msg.Dispose(); } } } case COM.IndexusMessage.StatusValue.Response: { #region response case #if DEBUG if (writeStats) { Console.WriteLine("Received Action: {0}", msg.Status.ToString()); } #endif // Server never should receive a Response from the client! msg.Action = COM.IndexusMessage.ActionValue.Error; string info = string.Format("[{0}]Error, the message should have the Status Request!", state.WorkSocket.RemoteEndPoint); Console.WriteLine(info); COM.Handler.LogHandler.Traffic(info); COM.Handler.LogHandler.Error(info); break; #endregion response case } } } } else { COM.Handler.LogHandler.Error("Cannot handle state because state is NULL"); Console.WriteLine("Cannot handle state because state is NULL"); } }
/// <summary> /// Handle each protocol message - its like single point of access for every provided possibility /// </summary> /// <param name="msg">A <see cref="IndexusMessage"/> object.</param> /// <param name="lastUsedServerNodeIp">The last used server node ip, this is mainly used in case of replication configuration.</param> /// <returns> /// the status if communication where sucessfully or if it failed. /// </returns> private static bool HandleProtocol(IndexusMessage msg, string lastUsedServerNodeIp) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log try { bool hostAvailable = false; if (ClientContext) { //new: check if host is available first bevor we send to prevent timeouts!!! hostAvailable = Sockets.ManageClientTcpSocketConnectionPoolFactory.CheckPool(msg.Hostname); } else { hostAvailable = Sockets.ManageServerTcpSocketConnectionPoolFactory.CheckPool(msg.Hostname); } if (hostAvailable || msg.Action == IndexusMessage.ActionValue.Ping) { if (msg.Send()) { Interlocked.Increment(ref counterSuccess); return true; } else { Interlocked.Increment(ref counterFailed); return false; } } else { // handling replicated caching in case primary node is not available if (Provider.Cache.IndexusDistributionCache.SharedCache.ReplicatedServers.Length > 0) { string current = msg.Hostname; bool take = false; foreach (IndexusServerSetting item in IndexusDistributionCache.ProviderSection.ReplicatedServers) { // handling first chain in list if(string.IsNullOrEmpty(lastUsedServerNodeIp)) take = true; if (item.IpAddress.Equals(lastUsedServerNodeIp)) { take = true; continue; } if (take) { msg.Hostname = item.IpAddress; bool result = HandleProtocol(msg, item.IpAddress); if(!result) Interlocked.Increment(ref counterFailed); else Interlocked.Increment(ref counterSuccess); return result; } } } Interlocked.Increment(ref counterFailedNodeNotAvailable); return false; } } catch (SocketException sEx) { // upon clientContext and the user defined replication mode the // system try to send the message to a different server node // Console.WriteLine(sEx.Message + " " + sEx.SocketErrorCode + " " + sEx.ErrorCode); if (ClientContext) { // doesn't matter if we are using replicated caching or distributed caching specfic server node need to be // disabled until the client enable it automatically again. Sockets.ManageClientTcpSocketConnectionPoolFactory.DisablePool(msg.Hostname); // in case first node of replicated servers is not available we receive an exception which // will force the program to move to next available node until it found one which is available if (Provider.Cache.IndexusDistributionCache.SharedCache.ReplicatedServers.Length > 0) { string current = msg.Hostname; bool take = false; foreach (IndexusServerSetting item in IndexusDistributionCache.ProviderSection.ReplicatedServers) { // handling first chain in list if (string.IsNullOrEmpty(lastUsedServerNodeIp)) take = true; if (item.IpAddress.Equals(lastUsedServerNodeIp)) { take = true; continue; } if (take) { msg.Hostname = item.IpAddress; bool result = HandleProtocol(msg, item.IpAddress); if (!result) Interlocked.Increment(ref counterFailed); else Interlocked.Increment(ref counterSuccess); return result; } } } else { Interlocked.Increment(ref counterFailed); return false; } } else { Sockets.ManageServerTcpSocketConnectionPoolFactory.DisablePool(msg.Hostname); } return false; } catch (Exception ex) { Interlocked.Increment(ref counterFailed); //if (1 == Provider.Cache.IndexusDistributionCache.ProviderSection.ClientSetting.LoggingEnable) //{ Handler.LogHandler.Fatal(string.Format("Unhandled Exception appears: {0} \n{1}", ex.Message, ex.StackTrace)); Console.WriteLine(string.Format("Unhandled Exception appears: {0} \n{1}", ex.Message, ex.StackTrace)); //} return false; } }
/// <summary> /// Clear cache on provided server node. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Clear(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log using (IndexusMessage msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.RemoveAll)) { if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } return HandleProtocol(msg, string.Empty); } }
/// <summary> /// Retrieve a List of <see cref="string"/> of all available key's on specific server node. /// </summary> /// <param name="host">The host represents the ip address of a server node.</param> /// <returns> /// the status if communication where sucessfully or if it failed. /// </returns> internal static List<string> GetAllKeys(string host) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log using (IndexusMessage msg = new IndexusMessage(Handler.Unique.NextUniqueId(), IndexusMessage.ActionValue.GetAllKeys)) { if (!string.IsNullOrEmpty(host)) { msg.Hostname = host; } if (!ClientContext) { msg.ClientContext = false; msg.Status = IndexusMessage.StatusValue.ReplicationRequest; } HandleProtocol(msg, string.Empty); return msg.Payload != null ? Formatters.Serialization.BinaryDeSerialize<List<string>>(msg.Payload) : new List<string>(); } }
/// <summary> /// Adding an item to cache. /// </summary> /// <param name="msg">The protocol message as <see cref="IndexusMessage"/> object.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Add(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterAdd); // handling compression if (compressionEnabled) { if (compressionMinSize > -1 && msg.Payload != null && msg.Payload.Length >= compressionMinSize) { msg.Payload = Formatters.Compression.Compress(msg.Payload); } } return HandleProtocol(msg, string.Empty); }
/// <summary> /// Handle each protocol message - its like single point of access for every provided possibility /// </summary> /// <param name="msg">A <see cref="IndexusMessage"/> object.</param> /// <param name="lastUsedServerNodeIp">The last used server node ip, this is mainly used in case of replication configuration.</param> /// <returns> /// the status if communication where sucessfully or if it failed. /// </returns> private static bool HandleProtocol(IndexusMessage msg, string lastUsedServerNodeIp) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log try { bool hostAvailable; if (ClientContext) { //new: check if host is available first bevor we send to prevent timeouts!!! hostAvailable = Sockets.ManageClientTcpSocketConnectionPoolFactory.CheckPool(msg.Hostname); } else { hostAvailable = Sockets.ManageServerTcpSocketConnectionPoolFactory.CheckPool(msg.Hostname); } if (hostAvailable || msg.Action == IndexusMessage.ActionValue.Ping) { if (msg.Send()) { Interlocked.Increment(ref counterSuccess); return(true); } Interlocked.Increment(ref counterFailed); return(false); } else if (ClientContext && Provider.Cache.IndexusDistributionCache.SharedCache.ServersList.Count > 1) { #region handling failover in distributed caching in case of primary node goes offline bool cached = false; foreach (Configuration.Client.IndexusServerSetting configEntry in Provider.Cache.IndexusDistributionCache.SharedCache.ServersList) { if (!cached && configEntry.IpAddress != msg.Hostname) { msg.Hostname = configEntry.IpAddress; //Getting stack overflow if using recursive call to HandleProtocol , so directly sending the msg hostAvailable = Sockets.ManageClientTcpSocketConnectionPoolFactory.CheckPool(msg.Hostname); if (hostAvailable || msg.Action == IndexusMessage.ActionValue.Ping) { if (msg.Send()) { Interlocked.Increment(ref counterSuccess); cached = true; } else { Interlocked.Increment(ref counterFailed); cached = false; } } else { cached = false; } } else if (cached) { break; //exit the loop if it finds the available host and msg sent successfully } } #endregion } else { if (ClientContext) { #region handling replicated caching in case primary node is not available if (Provider.Cache.IndexusDistributionCache.SharedCache.ReplicatedServers.Length > 0) { string current = msg.Hostname; bool take = false; foreach (IndexusServerSetting item in IndexusDistributionCache.ProviderSection.ReplicatedServers) { // handling first chain in list if (string.IsNullOrEmpty(lastUsedServerNodeIp)) { take = true; } if (item.IpAddress.Equals(lastUsedServerNodeIp)) { take = true; continue; } if (take) { msg.Hostname = item.IpAddress; bool result = HandleProtocol(msg, item.IpAddress); if (!result) { Interlocked.Increment(ref counterFailed); } else { Interlocked.Increment(ref counterSuccess); } return(result); } } } #endregion } else { #region handling replicated caching in case primary node is not available if (Provider.Server.IndexusServerReplicationCache.CurrentProvider.Servers.Length > 0) { string current = msg.Hostname; bool take = false; foreach (Configuration.Server.IndexusServerSetting item in IndexusServerReplicationCache.CurrentProvider.ServersList) // IndexusDistributionCache.ProviderSection.ReplicatedServers { // handling first chain in list if (string.IsNullOrEmpty(lastUsedServerNodeIp)) { take = true; } if (item.IpAddress.Equals(lastUsedServerNodeIp)) { take = true; continue; } if (take) { msg.Hostname = item.IpAddress; bool result = HandleProtocol(msg, item.IpAddress); if (!result) { Interlocked.Increment(ref counterFailed); } else { Interlocked.Increment(ref counterSuccess); } return(result); } } } #endregion } } Interlocked.Increment(ref counterFailedNodeNotAvailable); return(false); } catch (SocketException) { // upon clientContext and the user defined replication mode the // system try to send the message to a different server node // Console.WriteLine(sEx.Message + " " + sEx.SocketErrorCode + " " + sEx.ErrorCode); if (ClientContext) { // doesn't matter if we are using replicated caching or distributed caching specfic server node need to be // disabled until the client enable it automatically again. Sockets.ManageClientTcpSocketConnectionPoolFactory.DisablePool(msg.Hostname); // in case first node of replicated servers is not available we receive an exception which // will force the program to move to next available node until it found one which is available if (Provider.Cache.IndexusDistributionCache.SharedCache.ReplicatedServers.Length > 0) { string current = msg.Hostname; bool take = false; foreach (IndexusServerSetting item in IndexusDistributionCache.ProviderSection.ReplicatedServers) { // handling first chain in list if (string.IsNullOrEmpty(lastUsedServerNodeIp)) { take = true; } if (item.IpAddress.Equals(lastUsedServerNodeIp)) { take = true; continue; } if (take) { msg.Hostname = item.IpAddress; bool result = HandleProtocol(msg, item.IpAddress); if (!result) { Interlocked.Increment(ref counterFailed); } else { Interlocked.Increment(ref counterSuccess); } return(result); } } } else { Interlocked.Increment(ref counterFailed); return(false); } } else { Sockets.ManageServerTcpSocketConnectionPoolFactory.DisablePool(msg.Hostname); } return(false); } catch (Exception ex) { Interlocked.Increment(ref counterFailed); //if (1 == Provider.Cache.IndexusDistributionCache.ProviderSection.ClientSetting.LoggingEnable) //{ Handler.LogHandler.Fatal(string.Format("Unhandled Exception appears: {0} \n{1}", ex.Message, ex.StackTrace)); Console.WriteLine(string.Format("Unhandled Exception appears: {0} \n{1}", ex.Message, ex.StackTrace)); //} return(false); } }
/// <summary> /// Initializes a new instance of the <see cref="CacheException"/> class. /// </summary> /// <param name="title">The title.</param> /// <param name="action">The action.</param> /// <param name="status">The status.</param> /// <param name="innerException">The inner exception.</param> public CacheException(string title, IndexusMessage.ActionValue action, IndexusMessage.StatusValue status, Exception innerException) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log this.action = action; this.status = status; this.title = title; this.innerExceptionMessage = innerException.Message; this.source = innerException.Source; this.stackTrace = innerException.StackTrace; }
private void ProcessQueue() { #region Access Log #if TRACE { COM.Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log DistributeMessageToFamilyDelegate callback = null; int cnt = 0; do { Thread.Sleep(25); do { this.allDone.Reset(); cnt = this.replicationQueue.Count; if (cnt > 0) { #region Handle paralell replication logic COM.IndexusMessage msg = null; long id = -1; #region enqueue it here and send msg to distribute as argument lock (bulkObject) { msg = this.replicationQueue.Dequeue(); } #endregion if (msg != null) { if (!resendCount.ContainsKey(msg.Id)) { resendCount.Add(msg.Id, new ResendControlState(0)); } else { ResendControlState state = null; lock (bulkObject) { state = resendCount[msg.Id]; } if (state != null) { TimeSpan sp = DateTime.Now.Subtract(state.lastTry); if (sp.TotalMilliseconds < 250) { // Console.WriteLine("Not ready to resend!!! wait more time!!"); lock (bulkObject) { this.replicationQueue.Enqueue(msg); break; } } } } if (ServiceLogic.ServerFamily != null && ServiceLogic.ServerFamily.Count > 0) { // Loop through all available server foreach (string host in ServiceLogic.ServerFamily) { try { #region replicate to server nodes / familiy members if (msg.Status == SharedCache.WinServiceCommon.IndexusMessage.StatusValue.ReplicationRequest) { msg.ClientContext = false; msg.Hostname = host; callback = new DistributeMessageToFamilyDelegate(this.DistributeMessageToFamily); object[] args = new object[1] { msg }; this.threadPool.PostRequest(callback, args); } #endregion } catch (Exception ex) { // ??? } } } else { #region string msgNoServerAvailable = string.Format("could not call object distribution - Family Mode: {0}; Configured installation amount within network: {1}; IP:{2}:{3};", this.enableServiceFamilyMode, ServiceLogic.ServerFamily.Count, this.cacheIpAdress, this.cacheIpPort); COM.Handler.LogHandler.Error(msgNoServerAvailable); #if DEBUG Console.WriteLine(msgNoServerAvailable); #endif #endregion } } #endregion this.allDone.WaitOne(); } } while (cnt > 0); } while (true); }
/// <summary> /// Gets the specified MSG. /// </summary> /// <param name="msg">The protocol message as <see cref="IndexusMessage"/> object.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Get(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterGet); if (!ClientContext) { msg.ClientContext = false; msg.Status = IndexusMessage.StatusValue.ReplicationRequest; } if (HandleProtocol(msg, string.Empty)) { if (msg.Payload != null) { Interlocked.Increment(ref counterHitSuccess); } else { Interlocked.Increment(ref counterHitFailed); } // handling compression if (compressionEnabled) { if (compressionMinSize > -1 && Formatters.Compression.CheckHeader(msg.Payload)) { msg.Payload = Formatters.Compression.Decompress(msg.Payload); } } return true; } else { Interlocked.Increment(ref counterHitFailed); if (!ClientContext) return false; return true; } }
/// <summary> /// Removes the specified MSG. /// </summary> /// <param name="msg">The protocol message as <see cref="IndexusMessage"/> object.</param> /// <returns>the status if communication where sucessfully or if it failed.</returns> internal static bool Remove(IndexusMessage msg) { #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + typeof(CacheUtil).FullName + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log Interlocked.Increment(ref counterRemove); return HandleProtocol(msg, string.Empty); }
/// <summary> /// Distributes the message. /// <remarks> /// handling requested action of the object within the network. This been executed within its /// own thread and not with a delegate, delegates get blocked in previous implementations. /// </remarks> /// </summary> /// <param name="state">The MSG. A <see cref="T:SharedCache.WinServiceCommon.IndexusMessage"/> Object.</param> private void DistributeMessageToFamily(object state) { #region Access Log #if TRACE { COM.Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log COM.IndexusMessage msg = state as COM.IndexusMessage; // signal main thread to continue this.allDone.Set(); #region Logging if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { COM.Handler.LogHandler.SyncInfo( string.Format( COM.Constants.SYNCDEQUEUELOG, msg.Id, msg.Action, msg.Status ) ); } #endregion Logging try { switch (msg.Action) { case COM.IndexusMessage.ActionValue.Add: case COM.IndexusMessage.ActionValue.Remove: { COM.Provider.Server.IndexusServerReplicationCache.CurrentProvider.Distribute(msg); break; } } } catch (Exception ex) { #region exception logic string errorMsg = @"Distribution were not successfully. " + ex.Message; COM.Handler.LogHandler.Error(errorMsg); COM.Handler.LogHandler.SyncInfo(errorMsg); Console.WriteLine(errorMsg); lock (bulkObject) { int counter = 0; if (resendCount.ContainsKey(msg.Id)) { // first increment and then assign. counter = ++resendCount[msg.Id].count; resendCount[msg.Id].lastTry = DateTime.Now; } if (counter <= maxResend) { // reassign msg to queue this.replicationQueue.Enqueue(msg); } else { // after x-times to try to resend we remove it from the loop otherwise we run into an endless loop resendCount.Remove(msg.Id); COM.Handler.LogHandler.SyncFatalException(string.Format(@"The message {0} could not be replicated after {1} tries", msg.Id, maxResend), ex); #region Logging #if DEBUG Console.WriteLine(@"The message ID - {0} could not be replicated after {1} tries", msg.Id, maxResend); #endif #endregion } } #endregion exception logic } }