Example #1
0
        //Private method for reading results of the "get" command.
        private bool readValue(PooledSocket socket, out object value, out string key, out ulong unique)
        {
            string response = socket.ReadResponse();

            string[] parts = response.Split(' '); //Result line from server: "VALUE <key> <flags> <bytes> <cas unique>"
            if (parts[0] == "VALUE")
            {
                key = parts[1];
                SerializedType type  = (SerializedType)Enum.Parse(typeof(SerializedType), parts[2]);
                byte[]         bytes = new byte[Convert.ToUInt32(parts[3], CultureInfo.InvariantCulture)];
                if (parts.Length > 4)
                {
                    unique = Convert.ToUInt64(parts[4]);
                }
                else
                {
                    unique = 0;
                }
                socket.Read(bytes);
                socket.SkipUntilEndOfLine(); //Skip the trailing \r\n
                try
                {
                    value = Serializer.DeSerialize(bytes, type);
                }
                catch (Exception e)
                {
                    //If deserialization fails, return null
                    value = null;
                    logger.Error("Error deserializing object for key '" + key + "' of type " + type + ".", e);
                }
                return(true);
            }
            else
            {
                key    = null;
                value  = null;
                unique = 0;
                return(false);
            }
        }
Example #2
0
        /// <summary>
        /// Returns a socket to the pool.
        /// If the socket is dead, it will be destroyed.
        /// If there are more than MaxPoolSize sockets in the pool, it will be destroyed.
        /// If there are less than MinPoolSize sockets in the pool, it will always be put back.
        /// If there are something inbetween those values, the age of the socket is checked.
        /// If it is older than the SocketRecycleAge, it is destroyed, otherwise it will be
        /// put back in the pool.
        /// </summary>
        internal void Return(PooledSocket socket)
        {
            //If the socket is dead, destroy it.
            if (!socket.IsAlive)
            {
                Interlocked.Increment(ref deadsocketsonreturn);
                socket.Close();
            }
            else
            {
                //Clean up socket
                if (socket.Reset())
                {
                    Interlocked.Increment(ref dirtysocketsonreturn);
                }

                //Check pool size.
                if (queue.Count >= owner.MaxPoolSize)
                {
                    //If the pool is full, destroy the socket.
                    socket.Close();
                }
                else if (queue.Count > owner.MinPoolSize && DateTime.Now - socket.Created > owner.SocketRecycleAge)
                {
                    //If we have more than the minimum amount of sockets, but less than the max, and the socket is older than the recycle age, we destroy it.
                    socket.Close();
                }
                else
                {
                    //Put the socket back in the pool.
                    lock (queue)
                    {
                        queue.Enqueue(socket);
                    }
                }
            }
        }
Example #3
0
		internal void Execute(SocketPool pool, UseSocket use) {
			PooledSocket sock = null;
			try {
				//Acquire a socket
				sock = pool.Acquire();

				//Use the socket as a parameter to the delegate and return its result.
				if (sock != null) {
					use(sock);
				}
			} catch(Exception e) {
				logger.Error("Error in Execute: " + pool.Host, e);

				//socket is probably broken
				if (sock != null) {
					sock.Close();
				}
			}
			finally {
				if(sock != null) {
					sock.Dispose();
				}
			}
		}
Example #4
0
		/// <summary>
		/// Returns a socket to the pool.
		/// If the socket is dead, it will be destroyed.
		/// If there are more than MaxPoolSize sockets in the pool, it will be destroyed.
		/// If there are less than MinPoolSize sockets in the pool, it will always be put back.
		/// If there are something inbetween those values, the age of the socket is checked. 
		/// If it is older than the SocketRecycleAge, it is destroyed, otherwise it will be 
		/// put back in the pool.
		/// </summary>
		internal void Return(PooledSocket socket) {
			//If the socket is dead, destroy it.
			if (!socket.IsAlive) {
				Interlocked.Increment(ref deadsocketsonreturn);
				socket.Close();
			} else {
				//Clean up socket
				if (socket.Reset()) {
					Interlocked.Increment(ref dirtysocketsonreturn);
				}

				//Check pool size.
				if (queue.Count >= owner.MaxPoolSize) {
					//If the pool is full, destroy the socket.
					socket.Close();
				} else if (queue.Count > owner.MinPoolSize && DateTime.Now - socket.Created > owner.SocketRecycleAge) {
					//If we have more than the minimum amount of sockets, but less than the max, and the socket is older than the recycle age, we destroy it.
					socket.Close();
				} else {
					//Put the socket back in the pool.
					lock (queue) {
						queue.Enqueue(socket);
					}
				}
			}
		}
Example #5
0
		/// <summary>
		/// Gets a socket from the pool.
		/// If there are no free sockets, a new one will be created. If something goes
		/// wrong while creating the new socket, this pool's endpoint will be marked as dead
		/// and all subsequent calls to this method will return null until the retry interval
		/// has passed.
		/// </summary>
		internal PooledSocket Acquire() {
			//Do we have free sockets in the pool?
			//if so - return the first working one.
			//if not - create a new one.
			Interlocked.Increment(ref acquired);
			lock(queue) {
				while(queue.Count > 0) {
					PooledSocket socket = queue.Dequeue();
					if(socket != null && socket.IsAlive) {
						Interlocked.Increment(ref reusedsockets);
						return socket;
					}
					Interlocked.Increment(ref deadsocketsinpool);
				}
			}

			Interlocked.Increment(ref newsockets);
			//If we know the endpoint is dead, check if it is time for a retry, otherwise return null.
			if (isEndPointDead) {
				if (DateTime.Now > deadEndPointRetryTime) {
					//Retry
					isEndPointDead = false;
				} else {
					//Still dead
					return null;
				}
			} 

			//Try to create a new socket. On failure, mark endpoint as dead and return null.
			try {
				PooledSocket socket = new PooledSocket(this, endPoint, owner.SendReceiveTimeout, owner.ConnectTimeout);
				//Reset retry timer on success.
				deadEndPointSecondsUntilRetry = 1;
				return socket;
			}
			catch (Exception e) {
				Interlocked.Increment(ref failednewsockets);
				logger.Error("Error connecting to: " + endPoint.Address, e);
				//Mark endpoint as dead
				isEndPointDead = true;
				//Retry in 2 minutes
				deadEndPointRetryTime = DateTime.Now.AddSeconds(deadEndPointSecondsUntilRetry);
				if (deadEndPointSecondsUntilRetry < maxDeadEndPointSecondsUntilRetry) {
					deadEndPointSecondsUntilRetry = deadEndPointSecondsUntilRetry * 2; //Double retry interval until next time
				}
				return null;
			}
		}
 //Private method for reading results of the "get" command.
 private bool readValue(PooledSocket socket, out object value, out string key, out ulong unique)
 {
     string response = socket.ReadResponse();
     string[] parts = response.Split(' '); //Result line from server: "VALUE <key> <flags> <bytes> <cas unique>"
     if (parts[0] == "VALUE") {
         key = parts[1];
         SerializedType type = (SerializedType)Enum.Parse(typeof(SerializedType), parts[2]);
         byte[] bytes = new byte[Convert.ToUInt32(parts[3], CultureInfo.InvariantCulture)];
         if (parts.Length > 4) {
             unique = Convert.ToUInt64(parts[4]);
         } else {
             unique = 0;
         }
         socket.Read(bytes);
         socket.SkipUntilEndOfLine(); //Skip the trailing \r\n
         try {
             value = Serializer.DeSerialize(bytes, type);
         } catch (Exception e) {
             //If deserialization fails, return null
             value = null;
             logger.Error("Error deserializing object for key '" + key + "' of type " + type + ".", e);
         }
         return true;
     } else {
         key = null;
         value = null;
         unique = 0;
         return false;
     }
 }