michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: The implementation of a thread-safe client connection manager. michael@0: michael@0:
michael@0: Relation Diagram michael@0:
michael@0: michael@0:

michael@0: The implementation is structured into three areas, as illustrated michael@0: by the diagram above. michael@0: Facing the application is the Manager (green), which internally michael@0: maintains a Pool (yellow) of connections and waiting threads. michael@0: Both Manager and Pool rely on Operations (cyan) to provide the michael@0: actual connections. michael@0:

michael@0:

michael@0: In order to allow connection garbage collection, it is michael@0: imperative that hard object references between the areas are michael@0: restricted to the relations indicated by arrows in the diagram: michael@0:

michael@0: michael@0: michael@0:

michael@0: The following table shows a selection of classes and interfaces, michael@0: and their assignment to the three areas. michael@0:

michael@0:
michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0:
michael@0: {@link org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager} michael@0: michael@0: {@link org.apache.http.impl.conn.tsccm.AbstractConnPool} michael@0:
michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter} michael@0: michael@0: {@link org.apache.http.impl.conn.tsccm.ConnPoolByRoute} michael@0:
michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} michael@0: michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} michael@0:
michael@0: {@link org.apache.http.conn.ClientConnectionOperator} michael@0:
michael@0: {@link org.apache.http.conn.OperatedClientConnection} michael@0:
michael@0:
michael@0: michael@0:

michael@0: The Manager area has implementations for the connection management michael@0: interfaces {@link org.apache.http.conn.ClientConnectionManager} michael@0: and {@link org.apache.http.conn.ManagedClientConnection}. michael@0: The latter is an adapter from managed to operated connections, based on a michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPoolEntry}. michael@0:
michael@0: The Pool area shows an abstract pool class michael@0: {@link org.apache.http.impl.conn.tsccm.AbstractConnPool} michael@0: and a concrete implementation michael@0: {@link org.apache.http.impl.conn.tsccm.ConnPoolByRoute} michael@0: which uses the same basic algorithm as the michael@0: MultiThreadedHttpConnectionManager michael@0: in HttpClient 3.x. michael@0: A pool contains instances of michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPoolEntry}. michael@0: Most other classes in this package also belong to the Pool area. michael@0:
michael@0: In the Operations area, you will find only the interfaces for michael@0: operated connections as defined in the org.apache.http.conn package. michael@0: The connection manager will work with all correct implementations michael@0: of these interfaces. This package therefore does not define anything michael@0: specific to the Operations area. michael@0:

michael@0: michael@0:

michael@0: As you have surely noticed, the michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} michael@0: appears in both the Manager and Pool areas. michael@0: This is where things get tricky for connection garbage collection. michael@0:
michael@0: A connection pool may start a background thread to implement cleanup. michael@0: In that case, the connection pool will not be garbage collected until michael@0: it is shut down, since the background thread keeps a hard reference michael@0: to the pool. The pool itself keeps hard references to the pooled entries, michael@0: which in turn reference idle connections. Neither of these is subject michael@0: to garbage collection. michael@0: Only the shutdown of the pool will stop the background thread, michael@0: thereby enabling garbage collection of the pool objects. michael@0:
michael@0: A pool entry that is passed to an application by means of a connection michael@0: adapter will move from the Pool area to the Manager area. When the michael@0: connection is released by the application, the manager returns the michael@0: entry back to the pool. With that step, the pool entry moves from michael@0: the Manager area back to the Pool area. michael@0: While the entry is in the Manager area, the pool MUST NOT keep a michael@0: hard reference to it. michael@0:

michael@0: michael@0:

michael@0: The purpose of connection garbage collection is to detect when an michael@0: application fails to return a connection. In order to achieve this, michael@0: the only hard reference to the pool entry in the Manager area is michael@0: in the connection wrapper. The manager will not keep a hard reference michael@0: to the connection wrapper either, since that wrapper is effectively michael@0: moving to the Application area. michael@0: If the application drops it's reference to the connection wrapper, michael@0: that wrapper will be garbage collected, and with it the pool entry. michael@0:
michael@0: In order to detect garbage collection of pool entries handed out michael@0: to the application, the pool keeps a weak reference to the michael@0: entry. Instances of michael@0: {@link org.apache.http.impl.conn.tsccm.BasicPoolEntryRef} michael@0: combine the weak reference with information about the route for michael@0: which the pool entry was allocated. If one of these entry references michael@0: becomes stale, the pool can accommodate for the lost connection. michael@0: This is triggered either by a background thread waiting for the michael@0: references to be queued by the garbage collector, or by the michael@0: application calling a {@link michael@0: org.apache.http.conn.ClientConnectionManager#closeIdleConnections cleanup} michael@0: method of the connection manager. michael@0:
michael@0: Basically the same trick is used for detecting garbage collection michael@0: of the connection manager itself. The pool keeps a weak reference michael@0: to the connection manager that created it. However, this will work michael@0: only if there is a background thread to detect when that reference michael@0: is queued by the garbage collector. Otherwise, a finalizer of the michael@0: connection manager will shut down the pool and release it's resources. michael@0:

michael@0: michael@0: michael@0: michael@0: