Package: generic-connection-pool
generic-connection-poolis an extensible connection pool agnostic to the connection type it is managing.
It can be used for TCP, http, database or ssh connections.Featuresgeneric nature: can be used for any connection you desire (TCP, http, database, ssh, etc.)runtime agnostic: synchronous and asynchronous runtime supportedflexibility: flexable connection retention and recycling policyfully-typed: mypy type-checker compatibleGetting startedConnection pool supports the following configurations:background_collector: ifTruestarts a background worker that disposes expired and idle connections
maintaining requested pool state. IfFalsethe connections will be disposed on each connection release.dispose_batch_size: maximum number of expired and idle connections to be disposed on connection release
(if background collector is started the parameter is ignored).idle_timeout: inactivity time (in seconds) after which an extra connection will be disposed
(a connection considered as extra if the number of endpoint connection exceedsmin_idle).max_lifetime: number of seconds after which any connection will be disposed.min_idle: minimum number of connections in each endpoint the pool tries to hold. Connections that exceed
that number will be considered as extra and disposed afteridle_timeoutseconds of inactivity.max_size: maximum number of endpoint connections.total_max_size: maximum number of all connections in the pool.The following example illustrates how to create https pool:importsocketimportsslimporturllib.parsefromhttp.clientimportHTTPResponsefromtypingimportTuplefromgeneric_connection_pool.contrib.socketimportSslSocketConnectionManagerfromgeneric_connection_pool.threadingimportConnectionPoolHostname=strPort=intEndpoint=Tuple[Hostname,Port]Connection=socket.sockethttp_pool=ConnectionPool[Endpoint,Connection](SslSocketConnectionManager(ssl.create_default_context()),idle_timeout=30.0,max_lifetime=600.0,min_idle=3,max_size=20,total_max_size=100,background_collector=True,)deffetch(url:str,timeout:float=5.0)->None:url=urllib.parse.urlsplit(url)port=url.portor443ifurl.scheme=='https'else80withhttp_pool.connection(endpoint=(url.hostname,port),timeout=timeout)assock:request=('GET{path}HTTP/1.1\r\n''Host:{host}\r\n''\r\n''\r\n').format(host=url.hostname,path=url.path)sock.write(request.encode())response=HTTPResponse(sock)response.begin()status,body=response.getcode(),response.read(response.length)print(status)print(body)try:fetch('https://en.wikipedia.org/wiki/HTTP')# http connection openedfetch('https://en.wikipedia.org/wiki/Python_(programming_language)')# http connection reusedfinally:http_pool.close()… or database oneimportpsycopg2.extensionsfromgeneric_connection_pool.contrib.psycopg2importDbConnectionManagerfromgeneric_connection_pool.threadingimportConnectionPoolEndpoint=strConnection=psycopg2.extensions.connectiondsn_params=dict(dbname='postgres',user='postgres',password='secret')pg_pool=ConnectionPool[Endpoint,Connection](DbConnectionManager(dsn_params={'master':dict(dsn_params,host='db-master.local'),'replica-1':dict(dsn_params,host='db-replica-1.local'),'replica-2':dict(dsn_params,host='db-replica-2.local'),},),acquire_timeout=2.0,idle_timeout=60.0,max_lifetime=600.0,min_idle=3,max_size=10,total_max_size=15,background_collector=True,)try:# connection openedwithpg_pool.connection(endpoint='master')asconn:cur=conn.cursor()cur.execute("SELECT * FROM pg_stats;")print(cur.fetchone())# connection openedwithpg_pool.connection(endpoint='replica-1')asconn:cur=conn.cursor()cur.execute("SELECT * FROM pg_stats;")print(cur.fetchone())# connection reusedwithpg_pool.connection(endpoint='master')asconn:cur=conn.cursor()cur.execute("SELECT * FROM pg_stats;")print(cur.fetchone())finally:pg_pool.close()Seedocumentationfor more details.