mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-22 06:13:25 -07:00
fixed threading issues with http handler
This commit is contained in:
parent
837d71712e
commit
4b15113dd5
1 changed files with 44 additions and 44 deletions
|
@ -75,14 +75,6 @@ class HTTPHandler(object):
|
||||||
if not self.ssl_verify:
|
if not self.ssl_verify:
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
self.uri = None
|
|
||||||
self.data = None
|
|
||||||
self.request_type = 'GET'
|
|
||||||
self.output_format = 'raw'
|
|
||||||
self.return_response = False
|
|
||||||
self.return_type = False
|
|
||||||
self.callback = None
|
|
||||||
self.request_kwargs = {}
|
|
||||||
|
|
||||||
def make_request(self,
|
def make_request(self,
|
||||||
uri=None,
|
uri=None,
|
||||||
|
@ -101,23 +93,29 @@ class HTTPHandler(object):
|
||||||
|
|
||||||
Output: list
|
Output: list
|
||||||
"""
|
"""
|
||||||
|
if request_type not in self._valid_request_types:
|
||||||
self.uri = str(uri)
|
|
||||||
self.data = data
|
|
||||||
self.request_type = request_type.upper()
|
|
||||||
self.output_format = output_format.lower()
|
|
||||||
self.return_response = return_response
|
|
||||||
self.return_type = return_type
|
|
||||||
self.callback = callback
|
|
||||||
self.timeout = timeout or self.timeout
|
|
||||||
self.request_kwargs = request_kwargs
|
|
||||||
|
|
||||||
if self.request_type not in self._valid_request_types:
|
|
||||||
logger.debug("HTTP request made but unsupported request type given.")
|
logger.debug("HTTP request made but unsupported request type given.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
requests = []
|
||||||
|
|
||||||
if uri:
|
if uri:
|
||||||
request_urls = [urljoin(str(url), self.uri) for url in self.urls]
|
request_urls = [urljoin(str(url), uri) for url in self.urls]
|
||||||
|
|
||||||
|
for url in request_urls:
|
||||||
|
request = {
|
||||||
|
'uri': uri,
|
||||||
|
'url': url,
|
||||||
|
'output_format':output_format.lower(),
|
||||||
|
'request_type': request_type.upper(),
|
||||||
|
'return_type': return_type,
|
||||||
|
'data': data,
|
||||||
|
'return_response': return_response,
|
||||||
|
'callback': callback,
|
||||||
|
'timeout': timeout or self.timeout,
|
||||||
|
'request_kwargs': request_kwargs
|
||||||
|
}
|
||||||
|
requests.append(request)
|
||||||
|
|
||||||
if no_token:
|
if no_token:
|
||||||
self.headers.pop('X-Plex-Token', None)
|
self.headers.pop('X-Plex-Token', None)
|
||||||
|
@ -125,7 +123,7 @@ class HTTPHandler(object):
|
||||||
self.headers.update(headers)
|
self.headers.update(headers)
|
||||||
|
|
||||||
responses = []
|
responses = []
|
||||||
for r in self._http_requests_pool(request_urls):
|
for r in self._http_requests_pool(requests):
|
||||||
responses.append(r)
|
responses.append(r)
|
||||||
|
|
||||||
return responses[0]
|
return responses[0]
|
||||||
|
@ -134,23 +132,23 @@ class HTTPHandler(object):
|
||||||
logger.debug("HTTP request made but no uri endpoint provided.")
|
logger.debug("HTTP request made but no uri endpoint provided.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _http_requests_pool(self, urls, workers=10, chunk=None):
|
def _http_requests_pool(self, requests, workers=10, chunk=None):
|
||||||
"""Generator function to request urls in chunks"""
|
"""Generator function to request urls in chunks"""
|
||||||
# From cpython
|
# From cpython
|
||||||
if chunk is None:
|
if chunk is None:
|
||||||
chunk, extra = divmod(len(urls), workers * 4)
|
chunk, extra = divmod(len(requests), workers * 4)
|
||||||
if extra:
|
if extra:
|
||||||
chunk += 1
|
chunk += 1
|
||||||
if len(urls) == 0:
|
if len(requests) == 0:
|
||||||
chunk = 0
|
chunk = 0
|
||||||
|
|
||||||
if len(urls) == 1:
|
if len(requests) == 1:
|
||||||
yield self._http_requests_single(urls[0])
|
yield self._http_requests_single(requests[0])
|
||||||
else:
|
else:
|
||||||
pool = ThreadPool(workers)
|
pool = ThreadPool(workers)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for work in pool.imap_unordered(self._http_requests_single, urls, chunk):
|
for work in pool.imap_unordered(self._http_requests_single, requests, chunk):
|
||||||
yield work
|
yield work
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not self._silent:
|
if not self._silent:
|
||||||
|
@ -159,13 +157,13 @@ class HTTPHandler(object):
|
||||||
pool.close()
|
pool.close()
|
||||||
pool.join()
|
pool.join()
|
||||||
|
|
||||||
def _http_requests_single(self, url):
|
def _http_requests_single(self, urlproperties):
|
||||||
"""Request the data from the url"""
|
"""Request the data from the url"""
|
||||||
err = False
|
err = False
|
||||||
error_msg = "Failed to access uri endpoint %s. " % self.uri
|
error_msg = "Failed to access uri endpoint %s. " % urlproperties['uri']
|
||||||
try:
|
try:
|
||||||
r = self._session.request(self.request_type, url, headers=self.headers, data=self.data,
|
r = self._session.request(urlproperties['request_type'], urlproperties['url'], headers=self.headers, data=urlproperties['data'],
|
||||||
timeout=self.timeout, verify=self.ssl_verify, **self.request_kwargs)
|
timeout=urlproperties['timeout'], verify=self.ssl_verify, **urlproperties['request_kwargs'])
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
except requests.exceptions.Timeout as e:
|
except requests.exceptions.Timeout as e:
|
||||||
err = True
|
err = True
|
||||||
|
@ -188,7 +186,7 @@ class HTTPHandler(object):
|
||||||
if not self._silent:
|
if not self._silent:
|
||||||
logger.error(error_msg + "Uncaught exception: %s", e)
|
logger.error(error_msg + "Uncaught exception: %s", e)
|
||||||
|
|
||||||
if self.return_response:
|
if urlproperties['return_response']:
|
||||||
return r
|
return r
|
||||||
elif err:
|
elif err:
|
||||||
return None
|
return None
|
||||||
|
@ -198,31 +196,33 @@ class HTTPHandler(object):
|
||||||
response_headers = r.headers
|
response_headers = r.headers
|
||||||
|
|
||||||
if response_status in (200, 201):
|
if response_status in (200, 201):
|
||||||
return self._http_format_output(response_content, response_headers)
|
return self._http_format_output(response_content, response_headers, urlproperties)
|
||||||
|
|
||||||
def _http_format_output(self, response_content, response_headers):
|
def _http_format_output(self, response_content, response_headers, urlproperties):
|
||||||
"""Formats the request response to the desired type"""
|
"""Formats the request response to the desired type"""
|
||||||
try:
|
try:
|
||||||
if self.output_format == 'text':
|
output_format = urlproperties['output_format']
|
||||||
|
if output_format == 'text':
|
||||||
output = response_content.decode('utf-8', 'ignore')
|
output = response_content.decode('utf-8', 'ignore')
|
||||||
elif self.output_format == 'dict':
|
elif output_format == 'dict':
|
||||||
output = helpers.convert_xml_to_dict(response_content)
|
output = helpers.convert_xml_to_dict(response_content)
|
||||||
elif self.output_format == 'json':
|
elif output_format == 'json':
|
||||||
output = helpers.convert_xml_to_json(response_content)
|
output = helpers.convert_xml_to_json(response_content)
|
||||||
elif self.output_format == 'xml':
|
elif output_format == 'xml':
|
||||||
output = helpers.parse_xml(response_content)
|
output = helpers.parse_xml(response_content)
|
||||||
else:
|
else:
|
||||||
output = response_content
|
output = response_content
|
||||||
|
callback = urlproperties['callback']
|
||||||
|
if callback:
|
||||||
|
return callback(output)
|
||||||
|
|
||||||
if self.callback:
|
return_type = urlproperties['return_type']
|
||||||
return self.callback(output)
|
if return_type:
|
||||||
|
|
||||||
if self.return_type:
|
|
||||||
return output, response_headers['Content-Type']
|
return output, response_headers['Content-Type']
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not self._silent:
|
if not self._silent:
|
||||||
logger.warn("Failed format response from uri %s to %s error %s" % (self.uri, self.output_format, e))
|
logger.warn("Failed format response from uri %s to %s error %s" % (self.uri, output_format, e))
|
||||||
return None
|
return None
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue