/// <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));
            }
        }
Exemple #7
0
        /// <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));
        }
Exemple #9
0
        /// <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;
        }
Exemple #10
0
        /// <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);
		}
Exemple #19
0
        /// <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
            }
        }
		/// <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;
		}