proxy.core.connection.pool module#

proxy.py#

⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on Network monitoring, controls & Application development, testing, debugging.

copyright
  1. 2013-present by Abhinav Singh and contributors.

license

BSD, see LICENSE for more details.

class proxy.core.connection.pool.UpstreamConnectionPool[source]#

Bases: proxy.core.work.work.Work[proxy.core.connection.server.TcpServerConnection]

Manages connection pool to upstream servers.

UpstreamConnectionPool avoids need to reconnect with the upstream servers repeatedly when a reusable connection is available in the pool.

A separate pool is maintained for each upstream server. So internally, it’s a pool of pools.

Internal data structure maintains references to connection objects that pool owns or has borrowed. Borrowed connections are marked as NOT reusable.

For reusable connections only, pool listens for read events to detect broken connections. This can happen if pool has opened a connection, which was never used and eventually reaches upstream server timeout limit.

When a borrowed connection is returned back to the pool, the connection is marked as reusable again. However, if returned connection has already been closed, it is removed from the internal data structure.

TODO: Ideally, UpstreamConnectionPool must be shared across all cores to make SSL session cache to also work without additional out-of-bound synchronizations.

TODO: UpstreamConnectionPool currently WON’T work for HTTPS connection. This is because of missing support for session cache, session ticket, abbr TLS handshake and other necessary features to make it work.

NOTE: However, currently for all HTTP only upstream connections, UpstreamConnectionPool can be used to remove slow starts.

_abc_impl = <_abc._abc_data object>#
_add(conn: proxy.core.connection.server.TcpServerConnection) None[source]#

Adds a new connection to internal data structure.

_remove(fileno: int) None[source]#

Remove a connection by descriptor from the internal data structure.

acquire(addr: Tuple[str, int]) Tuple[bool, proxy.core.connection.server.TcpServerConnection][source]#

Returns a reusable connection from the pool.

If none exists, will create and return a new connection.

add(addr: Tuple[str, int]) proxy.core.connection.server.TcpServerConnection[source]#

Creates, connects and adds a new connection to the pool.

Returns newly created connection.

NOTE: You must not use the returned connection, instead use acquire.

connections: Dict[int, proxy.core.connection.server.TcpServerConnection]#
static create(*args: Any) proxy.core.connection.server.TcpServerConnection[source]#

Implementations are responsible for creation of work objects from incoming args. This helps keep work core agnostic to creation of externally defined work class objects.

async get_events() Dict[int, int][source]#

Returns read event flag for all reusable connections in the pool.

async handle_events(readables: List[int], _writables: List[int]) bool[source]#

Removes reusable connection from the pool.

When pool is the owner of connection, we don’t expect a read event from upstream server. A read event means either upstream closed the connection or connection has somehow reached an illegal state e.g. upstream sending data for previous connection acquisition lifecycle.

pools: Dict[Tuple[str, int], Set[proxy.core.connection.server.TcpServerConnection]]#
release(conn: proxy.core.connection.server.TcpServerConnection) None[source]#

Release a previously acquired connection.

Releasing a connection will shutdown and close the socket including internal pool cleanup.

retain(conn: proxy.core.connection.server.TcpServerConnection) None[source]#

Retained previously acquired connection in the pool for reusability.

uid: str#