2013-08-27 10 views
32

(modifica: Forse mi sbaglio nel significato di questo errore: indica che il pool di connessioni del mio CLIENT è pieno? O un pool di connessioni sul SERVER è pieno e questo è l'errore che viene fornito al mio client?)Posso cambiare la dimensione del pool di connessioni per il modulo "richieste" di Python?

Sto tentando di effettuare un numero elevato di richieste http in concomitanza con il modulo python threading e requests. Sto vedendo questo errore nei registri:

WARNING:requests.packages.urllib3.connectionpool:HttpConnectionPool is full, discarding connection: 

Che cosa posso fare per aumentare le dimensioni del pool di connessioni per le richieste?

risposta

70

Questo dovrebbe fare il trucco:

import requests 
sess = requests.Session() 
adapter = requests.adapters.HTTPAdapter(pool_connections=100, pool_maxsize=100) 
sess.mount('http://', adapter) 
resp = sess.get("/mypage") 
+5

Questo funziona per me. Dovrebbe essere contrassegnato come la risposta corretta. – reish

9

Nota: Utilizzare questa soluzione solo se non è possibile controllare la costruzione del pool di connessioni (come descritto nel @ risposta di Jahaja).

Il problema è che il urllib3 crea i pool su richiesta. Chiama il costruttore della classe urllib3.connectionpool.HTTPConnectionPool senza parametri. Le classi sono registrate in urllib3 .poolmanager.pool_classes_by_scheme. Il trucco è quello di sostituire le classi con i tuoi classi che hanno diversi parametri di default:

def patch_http_connection_pool(**constructor_kwargs): 
    """ 
    This allows to override the default parameters of the 
    HTTPConnectionPool constructor. 
    For example, to increase the poolsize to fix problems 
    with "HttpConnectionPool is full, discarding connection" 
    call this function with maxsize=16 (or whatever size 
    you want to give to the connection pool) 
    """ 
    from urllib3 import connectionpool, poolmanager 

    class MyHTTPConnectionPool(connectionpool.HTTPConnectionPool): 
     def __init__(self, *args,**kwargs): 
      kwargs.update(constructor_kwargs) 
      super(MyHTTPConnectionPool, self).__init__(*args,**kwargs) 
    poolmanager.pool_classes_by_scheme['http'] = MyHTTPConnectionPool 

quindi è possibile chiamare per fissare nuovi parametri di default. Assicurarsi che questo venga chiamato prima che venga effettuata qualsiasi connessione.

patch_http_connection_pool(maxsize=16) 

Se si utilizzano connessioni HTTPS è possibile creare una funzione simile:

def patch_https_connection_pool(**constructor_kwargs): 
    """ 
    This allows to override the default parameters of the 
    HTTPConnectionPool constructor. 
    For example, to increase the poolsize to fix problems 
    with "HttpSConnectionPool is full, discarding connection" 
    call this function with maxsize=16 (or whatever size 
    you want to give to the connection pool) 
    """ 
    from urllib3 import connectionpool, poolmanager 

    class MyHTTPSConnectionPool(connectionpool.HTTPSConnectionPool): 
     def __init__(self, *args,**kwargs): 
      kwargs.update(constructor_kwargs) 
      super(MyHTTPSConnectionPool, self).__init__(*args,**kwargs) 
    poolmanager.pool_classes_by_scheme['https'] = MyHTTPSConnectionPool 
+1

Le richieste hanno un'API incorporata per fornire i parametri del costruttore di ConnectionPool, l'applicazione di patch al costruttore non è necessaria. (Vedi la risposta di @ Jahaja.) – shazow

+1

Dipende dal contesto. Se hai il controllo sulla creazione di HTTPAdapter, usare la funzione di costruzione è la soluzione corretta. Ma ci sono casi in cui il pool di connessioni è inizializzato da qualche parte profondamente sepolto in qualche framework o libreria. In questi casi è possibile applicare una patch alla libreria o applicare una patch al costruttore del pool di connessione come descritto sopra. –

+0

Ho aggiunto un chiarimento alla mia soluzione. –

Problemi correlati