diff --git a/app/clients/email/aws_ses.py b/app/clients/email/aws_ses.py index f9d6e8723..7919a013e 100644 --- a/app/clients/email/aws_ses.py +++ b/app/clients/email/aws_ses.py @@ -62,6 +62,7 @@ class AwsSesClient(EmailClient): # before-call, after-call, after-call-error, request-created, response-received self._client.meta.events.register('request-created.ses.SendEmail', self.ses_request_created_hook) self._client.meta.events.register('response-received.ses.SendEmail', self.ses_response_received_hook) + self._client.meta.events.register('before-call.ses', self.ses_inject_connection_header) def ses_request_created_hook(self, **kwargs): # request created may be called multiple times if the request auto-retries. We want to count all these as the @@ -77,6 +78,11 @@ class AwsSesClient(EmailClient): def get_name(self): return self.name + def ses_inject_connection_header(self, params, **kwargs): + # keep underlying TLS connection open, so we do not spend lots of CPU + # and network time renegotiating TLS + params['headers']['Connection'] = 'Keep-Alive' + def send_email(self, source, to_addresses, @@ -148,3 +154,4 @@ def punycode_encode_email(email_address): # only the hostname should ever be punycode encoded. local, hostname = email_address.split('@') return '{}@{}'.format(local, hostname.encode('idna').decode('utf-8')) + diff --git a/app/clients/sms/firetext.py b/app/clients/sms/firetext.py index a8b803613..e4e5d3612 100644 --- a/app/clients/sms/firetext.py +++ b/app/clients/sms/firetext.py @@ -2,7 +2,8 @@ import json import logging from time import monotonic -from requests import request, RequestException +from requests import request, RequestException, Session +from requests.adapters import HTTPAdapter from app.clients.sms import (SmsClient, SmsClientResponseException) @@ -69,6 +70,9 @@ class FiretextClient(SmsClient): self.name = 'firetext' self.url = current_app.config.get('FIRETEXT_URL') self.statsd_client = statsd_client + # this uses urllib3 under the hood to create a connection pool + self.session = Session() + self.session.mount('https://', HTTPAdapter(pool_maxsize=32)) def get_name(self): return self.name @@ -103,8 +107,7 @@ class FiretextClient(SmsClient): response = None start_time = monotonic() try: - response = request( - "POST", + response = self.session.post( self.url, data=data, timeout=60 diff --git a/app/clients/sms/mmg.py b/app/clients/sms/mmg.py index 752ff7792..372ef0959 100644 --- a/app/clients/sms/mmg.py +++ b/app/clients/sms/mmg.py @@ -1,6 +1,8 @@ import json from time import monotonic -from requests import (request, RequestException) +from requests import (request, RequestException, Session) +from requests.adapters import HTTPAdapter + from app.clients.sms import (SmsClient, SmsClientResponseException) mmg_response_map = { @@ -75,6 +77,9 @@ class MMGClient(SmsClient): self.name = 'mmg' self.statsd_client = statsd_client self.mmg_url = current_app.config.get('MMG_URL') + # this uses urllib3 under the hood to create a connection pool + self.session = Session() + self.session.mount('https://', HTTPAdapter(pool_maxsize=32)) def record_outcome(self, success, response): status_code = response.status_code if response else 503 @@ -108,8 +113,8 @@ class MMGClient(SmsClient): response = None start_time = monotonic() try: - response = request( - "POST", + + response = self.session.post( self.mmg_url, data=json.dumps(data), headers={