简体   繁体   中英

cloudant python https connection pooling?

I've been doing some testing of https connection pooling from cloudant python requests as part of gunicorn request handling:

# -*- coding: utf-8 -

from requests.adapters import HTTPAdapter
import cloudant
import logging
import json

# log when new connections are started by urllib3
logging.basicConfig()
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

def app(environ, start_response):

    httpAdapter = HTTPAdapter(pool_connections=10, pool_maxsize=100)

    account = cloudant.Account('education', async=False)
    account._session.adapters['https://'] = httpAdapter

    db = account.database('foundbite')

    db_response = db.get( '_all_docs' )
    data = str.encode(json.dumps(db_response.json()))
    status = str(db_response.status_code)

    response_headers = [
        ('Content-type', 'application/json'),
        ('Content-Length', str(len(data))),
    ]
    start_response(status, response_headers)
    return iter([data])

If I make 5 requests, you can see that 5 new connections are started:

INFO: requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): education.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
INFO: requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): education.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
INFO: requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): education.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
INFO: requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): education.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
INFO: requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): education.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None

One option is to move the cloudant Account object instantiation outside of the request handler so that it can be shared between requests:

# -*- coding: utf-8 -

from requests.adapters import HTTPAdapter
import cloudant
import logging
import json

# log when new connections are started by urllib3
logging.basicConfig()
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

httpAdapter = HTTPAdapter(pool_connections=10, pool_maxsize=100)

account = cloudant.Account('education', async=False)
account._session.adapters['https://'] = httpAdapter

def app(environ, start_response):

    db = account.database('foundbite')

    db_response = db.get( '_all_docs' )
    data = str.encode(json.dumps(db_response.json()))
    status = str(db_response.status_code)

    response_headers = [
        ('Content-type', 'application/json'),
        ('Content-Length', str(len(data))),
    ]
    start_response(status, response_headers)
    return iter([data])

This time, only one https connection is created and that is used for all 5 requests:

INFO: requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): education.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /foundbite/_all_docs HTTP/1.1" 200 None

Question: This second approach will reduce the number of expensive https connections, however is this approach safe, ie is it threadsafe?

Requests uses urllib3 for its connection pooling, which is threadsafe. So as long as you don't call any methods on account which change its state (or only do so before you start making requests) you should be fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM