Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement connection retries #10

Merged
merged 3 commits into from
Oct 21, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions pypsrp/wsman.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ def __init__(self, server, max_envelope_size=153600, operation_timeout=20,
path="wsman", auth="negotiate", cert_validation=True,
connection_timeout=30, encryption='auto', proxy=None,
no_proxy=False, locale='en-US', data_locale=None,
read_timeout=30, **kwargs):
read_timeout=30, reconnection_retries=0,
reconnection_backoff=2.0, **kwargs):
"""
Class that handles WSMan transport over HTTP. This exposes a method per
action that takes in a resource and the header metadata required by
Expand Down Expand Up @@ -195,6 +196,11 @@ def __init__(self, server, max_envelope_size=153600, operation_timeout=20,
building the server SPN
negotiate_service: Override the service used when building the
server SPN, default='WSMAN'
:param int reconnection_retries: Number of retries on connection
problems
:param float reconnection_backoff: Number of seconds to backoff in
between reconnection attempts (first sleeps X, then sleeps 2*X,
4*X, 8*X, ...)
"""
log.info("Initialising WSMan class with maximum envelope size of %d "
"and operation timeout of %s"
Expand All @@ -207,7 +213,9 @@ def __init__(self, server, max_envelope_size=153600, operation_timeout=20,
self.transport = _TransportHTTP(server, port, username, password, ssl,
path, auth, cert_validation,
connection_timeout, encryption, proxy,
no_proxy, read_timeout, **kwargs)
no_proxy, read_timeout,
reconnection_retries,
reconnection_backoff, **kwargs)
self.max_envelope_size = max_envelope_size
self.operation_timeout = operation_timeout

Expand Down Expand Up @@ -623,7 +631,8 @@ def __init__(self, server, port=None, username=None, password=None,
ssl=True, path="wsman", auth="negotiate",
cert_validation=True, connection_timeout=30,
encryption='auto', proxy=None, no_proxy=False,
read_timeout=30, **kwargs):
read_timeout=30, reconnection_retries=0,
reconnection_backoff=2.0, **kwargs):
self.server = server
self.port = port if port is not None else (5986 if ssl else 5985)
self.username = username
Expand All @@ -639,6 +648,8 @@ def __init__(self, server, port=None, username=None, password=None,
self.cert_validation = cert_validation
self.connection_timeout = connection_timeout
self.read_timeout = read_timeout
self.reconnection_retries = reconnection_retries
self.reconnection_backoff = reconnection_backoff

# determine the message encryption logic
if encryption not in ["auto", "always", "never"]:
Expand Down Expand Up @@ -778,6 +789,22 @@ def _build_session(self):
elif self.no_proxy:
session.proxies = orig_proxy

# Retry on connection errors, with a backoff factor
retries = requests.packages.urllib3.util.retry.Retry(
jborean93 marked this conversation as resolved.
Show resolved Hide resolved
total=self.reconnection_retries,
connect=self.reconnection_retries,
status=self.reconnection_retries,
read=0,
backoff_factor=self.reconnection_backoff,
status_forcelist=(425, 429, 503),
)
session.mount('http://', requests.adapters.HTTPAdapter(
jborean93 marked this conversation as resolved.
Show resolved Hide resolved
max_retries=retries)
)
session.mount('https://', requests.adapters.HTTPAdapter(
max_retries=retries)
)

# set cert validation config
session.verify = self.cert_validation

Expand Down