Skip to content

Commit

Permalink
Allow variable pool size on BaseProtocol / Protocol (#57)
Browse files Browse the repository at this point in the history
* Reduce pool size to 4, but raise service account 150

* Add pool_size parameter
  • Loading branch information
jhatch28 authored Feb 10, 2021
1 parent a7d61e0 commit c7b34c2
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
5 changes: 3 additions & 2 deletions exchangelib/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Configuration(object):
account = Account(primary_smtp_address='[email protected]', credentials=credentials, autodiscover=True)
"""
def __init__(self, credentials, server=None, has_ssl=True, service_endpoint=None, auth_type=None, version=None):
def __init__(self, credentials, server=None, has_ssl=True, service_endpoint=None, auth_type=None, version=None, **kwargs):
if auth_type is not None and auth_type not in AUTH_TYPE_MAP:
raise ValueError('Unsupported auth type %s' % auth_type)
if not (server or service_endpoint):
Expand All @@ -43,7 +43,8 @@ def __init__(self, credentials, server=None, has_ssl=True, service_endpoint=None
service_endpoint=service_endpoint,
auth_type=auth_type,
credentials=credentials,
version=version
version=version,
**kwargs
)

@property
Expand Down
14 changes: 10 additions & 4 deletions exchangelib/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class BaseProtocol(object):
# The maximum number of sessions (== TCP connections, see below) we will open to this service endpoint. Keep this
# low unless you have an agreement with the Exchange admin on the receiving end to hammer the server and
# rate-limiting policies have been disabled for the connecting user.
# This pool is shared across all accounts using the same service account in a single process
SESSION_POOLSIZE = 4
# We want only 1 TCP connection per Session object. We may have lots of different credentials hitting the server and
# each credential needs its own session (NTLM auth will only send credentials once and then secure the connection,
Expand All @@ -51,7 +52,7 @@ class BaseProtocol(object):
# The adapter class to use for HTTP requests. Override this if you need e.g. proxy support or specific TLS versions
HTTP_ADAPTER_CLS = requests.adapters.HTTPAdapter

def __init__(self, service_endpoint, credentials, auth_type):
def __init__(self, service_endpoint, credentials, auth_type, pool_size=None):
if not isinstance(credentials, Credentials):
raise ValueError("'credentials' %r must be a Credentials instance" % credentials)
if auth_type is not None:
Expand All @@ -62,6 +63,7 @@ def __init__(self, service_endpoint, credentials, auth_type):
self.service_endpoint = service_endpoint
self.auth_type = auth_type
self._session_pool = None # Consumers need to fill the session pool themselves
self.pool_size = pool_size

def __del__(self):
# pylint: disable=bare-except
Expand Down Expand Up @@ -225,8 +227,9 @@ def __init__(self, *args, **kwargs):

# Try to behave nicely with the Exchange server. We want to keep the connection open between requests.
# We also want to re-use sessions, to avoid the NTLM auth handshake on every request.
self._session_pool = LifoQueue(maxsize=self.SESSION_POOLSIZE)
for _ in range(self.SESSION_POOLSIZE):
pool_size = self.pool_size or self.SESSION_POOLSIZE
self._session_pool = LifoQueue(maxsize=pool_size)
for _ in range(pool_size):
self._session_pool.put(self.create_session(), block=False)

if version:
Expand All @@ -245,7 +248,10 @@ def __init__(self, *args, **kwargs):
# larger than the connection pool so we have time to process data without idling the connection.
# Create the pool as the last thing here, since we may fail in the version or auth type guessing, which would
# leave open threads around to be garbage collected.
thread_poolsize = 4 * self.SESSION_POOLSIZE
if self.pool_size:
thread_poolsize = 4 * self.pool_size
else:
thread_poolsize = 4 * self.SESSION_POOLSIZE
self.thread_pool = ThreadPool(processes=thread_poolsize)

def get_timezones(self, timezones=None, return_full_timezone_data=False):
Expand Down

0 comments on commit c7b34c2

Please sign in to comment.