com.danga.MemCached
Class SockIOPool

java.lang.Object
  extended by com.danga.MemCached.SockIOPool

public class SockIOPool
extends java.lang.Object

This class is a connection pool for maintaning a pool of persistent connections
to memcached servers. The pool must be initialized prior to use. This should typically be early on
in the lifecycle of the JVM instance.

An example of initializing using defaults:


        static {
                String[] serverlist = { "cache0.server.com:12345", "cache1.server.com:12345" };

                SockIOPool pool = SockIOPool.getInstance();
                pool.setServers(serverlist);
                pool.initialize();      
        }
 

An example of initializing using defaults and providing weights for servers:

        static {
                String[] serverlist = { "cache0.server.com:12345", "cache1.server.com:12345" };
                Integer[] weights   = { new Integer(5), new Integer(2) };
                
                SockIOPool pool = SockIOPool.getInstance();
                pool.setServers(serverlist);
                pool.setWeights(weights);       
                pool.initialize();      
        }
  

An example of initializing overriding defaults:

        static {
                String[] serverlist     = { "cache0.server.com:12345", "cache1.server.com:12345" };
                Integer[] weights       = { new Integer(5), new Integer(2) };   
                int initialConnections  = 10;
                int minSpareConnections = 5;
                int maxSpareConnections = 50;   
                long maxIdleTime        = 1000 * 60 * 30;       // 30 minutes
                long maxBusyTime        = 1000 * 60 * 5;        // 5 minutes
                long maintThreadSleep   = 1000 * 5;                     // 5 seconds
                int     socketTimeOut       = 1000 * 3;                 // 3 seconds to block on reads
                int     socketConnectTO     = 1000 * 3;                 // 3 seconds to block on initial connections.  If 0, then will use blocking connect (default)
                boolean failover        = false;                        // turn off auto-failover in event of server down       
                boolean nagleAlg        = false;                        // turn off Nagle's algorithm on all sockets in pool    
                boolean aliveCheck      = false;                        // disable health check of socket on checkout

                SockIOPool pool = SockIOPool.getInstance();
                pool.setServers( serverlist );
                pool.setWeights( weights );     
                pool.setInitConn( initialConnections );
                pool.setMinConn( minSpareConnections );
                pool.setMaxConn( maxSpareConnections );
                pool.setMaxIdle( maxIdleTime );
                pool.setMaxBusyTime( maxBusyTime );
                pool.setMaintSleep( maintThreadSleep );
                pool.setSocketTO( socketTimeOut );
                pool.setNagle( nagleAlg );      
                pool.setHashingAlg( SockIOPool.NEW_COMPAT_HASH );
                pool.setAliveCheck( true );
                pool.initialize();      
        }
  
The easiest manner in which to initialize the pool is to set the servers and rely on defaults as in the first example.
After pool is initialized, a client will request a SockIO object by calling getSock with the cache key
The client must always close the SockIO object when finished, which will return the connection back to the pool.

An example of retrieving a SockIO object:

                SockIOPool.SockIO sock = SockIOPool.getInstance().getSock( key );
                try {
                        sock.write( "version\r\n" );    
                        sock.flush();   
                        System.out.println( "Version: " + sock.readLine() );    
                }
                catch (IOException ioe) { System.out.println( "io exception thrown" ) };        

                sock.close();   
 

Version:
1.5
Author:
greg whalin

Nested Class Summary
protected static class SockIOPool.MaintThread
          Class which extends thread and handles maintenance of the pool.
static class SockIOPool.SockIO
          MemCached Java client, utility class for Socket IO.
 
Field Summary
private  boolean aliveCheck
           
private  java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> availPool
           
private  java.util.List<java.lang.String> buckets
           
private  java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> busyPool
           
static int CONSISTENT_HASH
           
private  java.util.TreeMap<java.lang.Long,java.lang.String> consistentBuckets
           
private  java.util.Map<SockIOPool.SockIO,java.lang.Integer> deadPool
           
private  boolean failback
           
private  boolean failover
           
private  int hashingAlg
           
private  java.util.Map<java.lang.String,java.util.Date> hostDead
           
private  java.util.Map<java.lang.String,java.lang.Long> hostDeadDur
           
private  java.util.concurrent.locks.ReentrantLock hostDeadLock
           
private  int initConn
           
private  boolean initialized
           
private static org.apache.log4j.Logger log
           
private  long maintSleep
           
private  SockIOPool.MaintThread maintThread
           
static long MAX_RETRY_DELAY
           
private  long maxBusyTime
           
private  int maxConn
           
private  int maxCreate
           
private  long maxIdle
           
private static java.lang.ThreadLocal<java.security.MessageDigest> MD5
           
private  int minConn
           
private  boolean nagle
           
static int NATIVE_HASH
           
static int NEW_COMPAT_HASH
           
static int OLD_COMPAT_HASH
           
private  int poolMultiplier
           
private static java.util.Map<java.lang.String,SockIOPool> pools
           
private  java.lang.String[] servers
           
private  int socketConnectTO
           
private  int socketTO
           
private  java.lang.Integer totalWeight
           
private  java.lang.Integer[] weights
           
private static java.lang.Integer ZERO
           
 
Constructor Summary
protected SockIOPool()
           
 
Method Summary
protected  void addSocketToPool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool, java.lang.String host, SockIOPool.SockIO socket)
          Adds a socket to a given pool for the given host.
private  void checkIn(SockIOPool.SockIO socket)
          Returns a socket to the avail pool.
private  void checkIn(SockIOPool.SockIO socket, boolean addToAvail)
          Checks a SockIO object in with the pool.
protected  void clearHostFromPool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool, java.lang.String host)
          Closes and removes all sockets from specified pool for host.
protected  void closePool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool)
          Closes all sockets in the passed in pool.
protected  SockIOPool.SockIO createSocket(java.lang.String host)
          Creates a new SockIO obj for the given server.
private  java.lang.Long findPointFor(java.lang.Long hv)
          Gets the first available key equal or above the given one, if none found, returns the first k in the bucket
 boolean getAliveCheck()
          Returns the current status of the aliveCheck flag.
private  long getBucket(java.lang.String key, java.lang.Integer hashCode)
           
 SockIOPool.SockIO getConnection(java.lang.String host)
          Returns a SockIO object from the pool for the passed in host.
 boolean getFailback()
          Returns current state of failover flag.
 boolean getFailover()
          Returns current state of failover flag.
private  long getHash(java.lang.String key, java.lang.Integer hashCode)
          Returns a bucket to check for a given key.
 int getHashingAlg()
          Returns current status of customHash flag
 java.lang.String getHost(java.lang.String key)
           
 java.lang.String getHost(java.lang.String key, java.lang.Integer hashcode)
          Gets the host that a particular key / hashcode resides on.
 int getInitConn()
          Returns the current setting for the initial number of connections per server in the available pool.
static SockIOPool getInstance()
          Single argument version of factory used for back compat.
static SockIOPool getInstance(java.lang.String poolName)
          Factory to create/retrieve new pools given a unique poolName.
 long getMaintSleep()
          Returns the current maint thread sleep time.
 long getMaxBusy()
          Returns the current max busy setting.
 int getMaxConn()
          Returns the maximum number of spare connections allowed in available pool.
 long getMaxIdle()
          Returns the current max idle setting.
 int getMinConn()
          Returns the minimum number of spare connections in available pool.
 boolean getNagle()
          Returns current status of nagle flag
 java.lang.String[] getServers()
          Returns the current list of all cache servers.
 SockIOPool.SockIO getSock(java.lang.String key)
          Returns appropriate SockIO object given string cache key.
 SockIOPool.SockIO getSock(java.lang.String key, java.lang.Integer hashCode)
          Returns appropriate SockIO object given string cache key and optional hashcode.
 int getSocketConnectTO()
          Returns the socket timeout for connect.
 int getSocketTO()
          Returns the socket timeout for reads.
 java.lang.Integer[] getWeights()
          Returns the current list of weights.
 void initialize()
          Initializes the pool.
 boolean isInitialized()
          Returns state of pool.
private static long md5HashingAlg(java.lang.String key)
          Internal private hashing method.
private static long newCompatHashingAlg(java.lang.String key)
          Internal private hashing method.
private static long origCompatHashingAlg(java.lang.String key)
          Internal private hashing method.
private  void populateBuckets()
           
private  void populateConsistentBuckets()
           
protected  void removeSocketFromPool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool, java.lang.String host, SockIOPool.SockIO socket)
          Removes a socket from specified pool for host.
protected  void selfMaint()
          Runs self maintenance on all internal pools.
 void setAliveCheck(boolean aliveCheck)
          Sets the aliveCheck flag for the pool.
 void setFailback(boolean failback)
          Sets the failback flag for the pool.
 void setFailover(boolean failover)
          Sets the failover flag for the pool.
 void setHashingAlg(int alg)
          Sets the hashing algorithm we will use.
 void setInitConn(int initConn)
          Sets the initial number of connections per server in the available pool.
 void setMaintSleep(long maintSleep)
          Set the sleep time between runs of the pool maintenance thread.
 void setMaxBusyTime(long maxBusyTime)
          Sets the max busy time for threads in the busy pool.
 void setMaxConn(int maxConn)
          Sets the maximum number of spare connections allowed in our available pool.
 void setMaxIdle(long maxIdle)
          Sets the max idle time for threads in the available pool.
 void setMinConn(int minConn)
          Sets the minimum number of spare connections to maintain in our available pool.
 void setNagle(boolean nagle)
          Sets the Nagle alg flag for the pool.
 void setServers(java.lang.String[] servers)
          Sets the list of all cache servers.
 void setSocketConnectTO(int socketConnectTO)
          Sets the socket timeout for connect.
 void setSocketTO(int socketTO)
          Sets the socket timeout for reads.
 void setWeights(java.lang.Integer[] weights)
          Sets the list of weights to apply to the server list.
 void shutDown()
          Shuts down the pool.
protected  void startMaintThread()
          Starts the maintenance thread.
protected  void stopMaintThread()
          Stops the maintenance thread.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

private static org.apache.log4j.Logger log

pools

private static java.util.Map<java.lang.String,SockIOPool> pools

MD5

private static java.lang.ThreadLocal<java.security.MessageDigest> MD5

ZERO

private static final java.lang.Integer ZERO

NATIVE_HASH

public static final int NATIVE_HASH
See Also:
Constant Field Values

OLD_COMPAT_HASH

public static final int OLD_COMPAT_HASH
See Also:
Constant Field Values

NEW_COMPAT_HASH

public static final int NEW_COMPAT_HASH
See Also:
Constant Field Values

CONSISTENT_HASH

public static final int CONSISTENT_HASH
See Also:
Constant Field Values

MAX_RETRY_DELAY

public static final long MAX_RETRY_DELAY
See Also:
Constant Field Values

maintThread

private SockIOPool.MaintThread maintThread

initialized

private boolean initialized

maxCreate

private int maxCreate

poolMultiplier

private int poolMultiplier

initConn

private int initConn

minConn

private int minConn

maxConn

private int maxConn

maxIdle

private long maxIdle

maxBusyTime

private long maxBusyTime

maintSleep

private long maintSleep

socketTO

private int socketTO

socketConnectTO

private int socketConnectTO

aliveCheck

private boolean aliveCheck

failover

private boolean failover

failback

private boolean failback

nagle

private boolean nagle

hashingAlg

private int hashingAlg

hostDeadLock

private final java.util.concurrent.locks.ReentrantLock hostDeadLock

servers

private java.lang.String[] servers

weights

private java.lang.Integer[] weights

totalWeight

private java.lang.Integer totalWeight

buckets

private java.util.List<java.lang.String> buckets

consistentBuckets

private java.util.TreeMap<java.lang.Long,java.lang.String> consistentBuckets

hostDead

private java.util.Map<java.lang.String,java.util.Date> hostDead

hostDeadDur

private java.util.Map<java.lang.String,java.lang.Long> hostDeadDur

availPool

private java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> availPool

busyPool

private java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> busyPool

deadPool

private java.util.Map<SockIOPool.SockIO,java.lang.Integer> deadPool
Constructor Detail

SockIOPool

protected SockIOPool()
Method Detail

getInstance

public static SockIOPool getInstance(java.lang.String poolName)
Factory to create/retrieve new pools given a unique poolName.

Parameters:
poolName - unique name of the pool
Returns:
instance of SockIOPool

getInstance

public static SockIOPool getInstance()
Single argument version of factory used for back compat. Simply creates a pool named "default".

Returns:
instance of SockIOPool

setServers

public void setServers(java.lang.String[] servers)
Sets the list of all cache servers.

Parameters:
servers - String array of servers [host:port]

getServers

public java.lang.String[] getServers()
Returns the current list of all cache servers.

Returns:
String array of servers [host:port]

setWeights

public void setWeights(java.lang.Integer[] weights)
Sets the list of weights to apply to the server list. This is an int array with each element corresponding to an element
in the same position in the server String array.

Parameters:
weights - Integer array of weights

getWeights

public java.lang.Integer[] getWeights()
Returns the current list of weights.

Returns:
int array of weights

setInitConn

public void setInitConn(int initConn)
Sets the initial number of connections per server in the available pool.

Parameters:
initConn - int number of connections

getInitConn

public int getInitConn()
Returns the current setting for the initial number of connections per server in the available pool.

Returns:
number of connections

setMinConn

public void setMinConn(int minConn)
Sets the minimum number of spare connections to maintain in our available pool.

Parameters:
minConn - number of connections

getMinConn

public int getMinConn()
Returns the minimum number of spare connections in available pool.

Returns:
number of connections

setMaxConn

public void setMaxConn(int maxConn)
Sets the maximum number of spare connections allowed in our available pool.

Parameters:
maxConn - number of connections

getMaxConn

public int getMaxConn()
Returns the maximum number of spare connections allowed in available pool.

Returns:
number of connections

setMaxIdle

public void setMaxIdle(long maxIdle)
Sets the max idle time for threads in the available pool.

Parameters:
maxIdle - idle time in ms

getMaxIdle

public long getMaxIdle()
Returns the current max idle setting.

Returns:
max idle setting in ms

setMaxBusyTime

public void setMaxBusyTime(long maxBusyTime)
Sets the max busy time for threads in the busy pool.

Parameters:
maxBusyTime - idle time in ms

getMaxBusy

public long getMaxBusy()
Returns the current max busy setting.

Returns:
max busy setting in ms

setMaintSleep

public void setMaintSleep(long maintSleep)
Set the sleep time between runs of the pool maintenance thread. If set to 0, then the maint thread will not be started.

Parameters:
maintSleep - sleep time in ms

getMaintSleep

public long getMaintSleep()
Returns the current maint thread sleep time.

Returns:
sleep time in ms

setSocketTO

public void setSocketTO(int socketTO)
Sets the socket timeout for reads.

Parameters:
socketTO - timeout in ms

getSocketTO

public int getSocketTO()
Returns the socket timeout for reads.

Returns:
timeout in ms

setSocketConnectTO

public void setSocketConnectTO(int socketConnectTO)
Sets the socket timeout for connect.

Parameters:
socketConnectTO - timeout in ms

getSocketConnectTO

public int getSocketConnectTO()
Returns the socket timeout for connect.

Returns:
timeout in ms

setFailover

public void setFailover(boolean failover)
Sets the failover flag for the pool. If this flag is set to true, and a socket fails to connect,
the pool will attempt to return a socket from another server
if one exists. If set to false, then getting a socket
will return null if it fails to connect to the requested server.

Parameters:
failover - true/false

getFailover

public boolean getFailover()
Returns current state of failover flag.

Returns:
true/false

setFailback

public void setFailback(boolean failback)
Sets the failback flag for the pool. If this is true and we have marked a host as dead, will try to bring it back. If it is false, we will never try to resurrect a dead host.

Parameters:
failback - true/false

getFailback

public boolean getFailback()
Returns current state of failover flag.

Returns:
true/false

setAliveCheck

public void setAliveCheck(boolean aliveCheck)
Sets the aliveCheck flag for the pool. When true, this will attempt to talk to the server on every connection checkout to make sure the connection is still valid. This adds extra network chatter and thus is defaulted off. May be useful if you want to ensure you do not have any problems talking to the server on a dead connection.

Parameters:
aliveCheck - true/false

getAliveCheck

public boolean getAliveCheck()
Returns the current status of the aliveCheck flag.

Returns:
true / false

setNagle

public void setNagle(boolean nagle)
Sets the Nagle alg flag for the pool. If false, will turn off Nagle's algorithm on all sockets created.

Parameters:
nagle - true/false

getNagle

public boolean getNagle()
Returns current status of nagle flag

Returns:
true/false

setHashingAlg

public void setHashingAlg(int alg)
Sets the hashing algorithm we will use. The types are as follows. SockIOPool.NATIVE_HASH (0) - native String.hashCode() - fast (cached) but not compatible with other clients SockIOPool.OLD_COMPAT_HASH (1) - original compatibility hashing alg (works with other clients) SockIOPool.NEW_COMPAT_HASH (2) - new CRC32 based compatibility hashing algorithm (fast and works with other clients)

Parameters:
alg - int value representing hashing algorithm

getHashingAlg

public int getHashingAlg()
Returns current status of customHash flag

Returns:
true/false

origCompatHashingAlg

private static long origCompatHashingAlg(java.lang.String key)
Internal private hashing method. This is the original hashing algorithm from other clients. Found to be slow and have poor distribution.

Parameters:
key - String to hash
Returns:
hashCode for this string using our own hashing algorithm

newCompatHashingAlg

private static long newCompatHashingAlg(java.lang.String key)
Internal private hashing method. This is the new hashing algorithm from other clients. Found to be fast and have very good distribution. UPDATE: This is dog slow under java

Parameters:
key -
Returns:

md5HashingAlg

private static long md5HashingAlg(java.lang.String key)
Internal private hashing method. MD5 based hash algorithm for use in the consistent hashing approach.

Parameters:
key -
Returns:

getHash

private long getHash(java.lang.String key,
                     java.lang.Integer hashCode)
Returns a bucket to check for a given key.

Parameters:
key - String key cache is stored under
Returns:
int bucket

getBucket

private long getBucket(java.lang.String key,
                       java.lang.Integer hashCode)

findPointFor

private java.lang.Long findPointFor(java.lang.Long hv)
Gets the first available key equal or above the given one, if none found, returns the first k in the bucket

Parameters:
k - key
Returns:

initialize

public void initialize()
Initializes the pool.


populateBuckets

private void populateBuckets()

populateConsistentBuckets

private void populateConsistentBuckets()

isInitialized

public boolean isInitialized()
Returns state of pool.

Returns:
true if initialized.

createSocket

protected SockIOPool.SockIO createSocket(java.lang.String host)
Creates a new SockIO obj for the given server. If server fails to connect, then return null and do not try
again until a duration has passed. This duration will grow
by doubling after each failed attempt to connect.

Parameters:
host - host:port to connect to
Returns:
SockIO obj or null if failed to create

getHost

public java.lang.String getHost(java.lang.String key)
Parameters:
key -
Returns:

getHost

public java.lang.String getHost(java.lang.String key,
                                java.lang.Integer hashcode)
Gets the host that a particular key / hashcode resides on.

Parameters:
key -
hashcode -
Returns:

getSock

public SockIOPool.SockIO getSock(java.lang.String key)
Returns appropriate SockIO object given string cache key.

Parameters:
key - hashcode for cache key
Returns:
SockIO obj connected to server

getSock

public SockIOPool.SockIO getSock(java.lang.String key,
                                 java.lang.Integer hashCode)
Returns appropriate SockIO object given string cache key and optional hashcode. Trys to get SockIO from pool. Fails over to additional pools in event of server failure.

Parameters:
key - hashcode for cache key
hashCode - if not null, then the int hashcode to use
Returns:
SockIO obj connected to server

getConnection

public SockIOPool.SockIO getConnection(java.lang.String host)
Returns a SockIO object from the pool for the passed in host. Meant to be called from a more intelligent method
which handles choosing appropriate server
and failover.

Parameters:
host - host from which to retrieve object
Returns:
SockIO object or null if fail to retrieve one

addSocketToPool

protected void addSocketToPool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool,
                               java.lang.String host,
                               SockIOPool.SockIO socket)
Adds a socket to a given pool for the given host. THIS METHOD IS NOT THREADSAFE, SO BE CAREFUL WHEN USING! Internal utility method.

Parameters:
pool - pool to add to
host - host this socket is connected to
socket - socket to add

removeSocketFromPool

protected void removeSocketFromPool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool,
                                    java.lang.String host,
                                    SockIOPool.SockIO socket)
Removes a socket from specified pool for host. THIS METHOD IS NOT THREADSAFE, SO BE CAREFUL WHEN USING! Internal utility method.

Parameters:
pool - pool to remove from
host - host pool
socket - socket to remove

clearHostFromPool

protected void clearHostFromPool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool,
                                 java.lang.String host)
Closes and removes all sockets from specified pool for host. THIS METHOD IS NOT THREADSAFE, SO BE CAREFUL WHEN USING! Internal utility method.

Parameters:
pool - pool to clear
host - host to clear

checkIn

private void checkIn(SockIOPool.SockIO socket,
                     boolean addToAvail)
Checks a SockIO object in with the pool. This will remove SocketIO from busy pool, and optionally
add to avail pool.

Parameters:
socket - socket to return
addToAvail - add to avail pool if true

checkIn

private void checkIn(SockIOPool.SockIO socket)
Returns a socket to the avail pool. This is called from SockIO.close(). Calling this method
directly without closing the SockIO object first
will cause an IOException to be thrown.

Parameters:
socket - socket to return

closePool

protected void closePool(java.util.Map<java.lang.String,java.util.Map<SockIOPool.SockIO,java.lang.Long>> pool)
Closes all sockets in the passed in pool. Internal utility method.

Parameters:
pool - pool to close

shutDown

public void shutDown()
Shuts down the pool. Cleanly closes all sockets.
Stops the maint thread.
Nulls out all internal maps


startMaintThread

protected void startMaintThread()
Starts the maintenance thread. This thread will manage the size of the active pool
as well as move any closed, but not checked in sockets
back to the available pool.


stopMaintThread

protected void stopMaintThread()
Stops the maintenance thread.


selfMaint

protected void selfMaint()
Runs self maintenance on all internal pools. This is typically called by the maintenance thread to manage pool size.



Copyright © 2005 - greg whalin