/// <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> /// Removes socket /// </summary> /// <param name="state">The state.</param> private void RemoveSocket(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 Socket sock = state.WorkSocket; try { lock (this.conntectedSockets) { if (this.conntectedSockets.Contains(state)) { this.conntectedSockets.Remove(state); Interlocked.Decrement(ref this.socketCount); } } #if DEBUG Console.WriteLine("Connection Count {0}", this.socketCount); #endif } catch (Exception ex) { #if DEBUG Console.WriteLine("Excpetion: " + ex); #endif if (1 == COM.Provider.Server.IndexusServerReplicationCache.ProviderSection.ServerSetting.LoggingEnable) { COM.Handler.LogHandler.Error("Exception in RemoveSocket", ex); } } try { lock (this.conntectedHt) { if (sock != null && (this.conntectedHt.ContainsKey(sock))) { object socketTemp = this.conntectedHt[sock]; if (this.conntectedHt.ContainsKey(socketTemp)) { if (this.conntectedHt.ContainsKey(this.conntectedHt[socketTemp])) { this.conntectedHt.Remove(sock); if (sock.Equals(this.conntectedHt[socketTemp])) { this.conntectedHt.Remove(socketTemp); } else { object value, key = socketTemp; while (true) { value = this.conntectedHt[key]; if (sock.Equals(value)) { this.conntectedHt[key] = socketTemp; break; } else if (this.conntectedHt.ContainsKey(value)) { key = value; } else { // chain is broken. break; } } } } else { COM.Handler.LogHandler.Info("Socket is not in connected Hash table"); } } } } } catch (Exception ex) { Console.WriteLine("Excpetion: " + ex); } try { if (sock != null) { sock.Shutdown(SocketShutdown.Both); // sock.Close(); if (sock != null) sock = null; // shutdown the state state = null; } } catch (Exception ex) { Console.WriteLine("Excpetion: " + ex); } }
/// <summary> /// Sends the response. /// </summary> /// <param name="state">The state.</param> /// <param name="response">The response.</param> private void SendResponse(COM.Sockets.SharedCacheStateObject state, COM.IndexusMessage response) { #region Access Log #if TRACE { COM.Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log // adding the protocol header !!!! very important byte[] arr = COM.Handler.UtilByte.CreateMessageHeader(response.GetBytes()); // manage first state object values before sending back data; state.DataBigBuffer = arr; state.MessageLength = arr.LongLength; // start async send this.Send(state); }
/// <summary> /// Sends the specified state. /// </summary> /// <param name="state">The state.</param> private void Send(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) { if (state.WorkSocket != null) { Socket socket = state.WorkSocket; if (state.DataBigBuffer != null && state.DataBigBuffer.Length > 0) { // Thread.Sleep(1); // todo: count is not good to use since its a int and not long value!!! socket.BeginSend(state.DataBigBuffer, 0, state.DataBigBuffer.Length, 0, new AsyncCallback(this.SendCallback), state); } else { // handler is now ready to receive more data from client //TimeSpan sp = DateTime.Now.Subtract(state.AliveTimeStamp); //Console.WriteLine("Send:" + sp.TotalMilliseconds); state.ReadHeader = true; state.AliveTimeStamp = DateTime.Now; state.AlreadySent = 0; state.DataBigBuffer = null;// new byte[COM.Sockets.SharedCacheStateObject.BufferSize * 2]; state.MessageLength = 0; state.AlreadyRead = 0; socket.BeginReceive(state.Buffer, 0, COM.Sockets.SharedCacheStateObject.BufferSize, 0, new AsyncCallback(this.ReadCallback), state); } } else { Console.WriteLine(@"State worker socket is NULL"); COM.Handler.LogHandler.Error(@"State worker socket is NULL"); } } else { Console.WriteLine("Cannot handle state because state is NULL"); COM.Handler.LogHandler.Error("Cannot handle state because state is NULL"); } }
/// <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); } }