From 1a80fc5a0e093c5072263b3c3b991538619510cd Mon Sep 17 00:00:00 2001 From: the31k Date: Wed, 19 Jul 2017 01:35:19 +0300 Subject: [PATCH 1/3] Per-thread singletons --- telebot/util.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/telebot/util.py b/telebot/util.py index f524577..ab7650d 100644 --- a/telebot/util.py +++ b/telebot/util.py @@ -17,6 +17,9 @@ except ImportError: from telebot import logger +thread_local = threading.local() + + class WorkerThread(threading.Thread): count = 0 @@ -242,3 +245,12 @@ def extract_arguments(text): regexp = re.compile("\/\w*(@\w*)*\s*([\s\S]*)",re.IGNORECASE) result = regexp.match(text) return result.group(2) if is_command(text) else None + + +def per_thread(key, construct_value): + try: + return getattr(thread_local, key) + except AttributeError: + value = construct_value() + setattr(thread_local, key, value) + return value From feec19b7f414f0edf3e889ff07e8a44c8a02d0b4 Mon Sep 17 00:00:00 2001 From: the31k Date: Wed, 19 Jul 2017 01:35:44 +0300 Subject: [PATCH 2/3] Use per-thread requests sessions Reason is requests.Session is not thread-safe See: https://github.com/requests/requests/issues/2766 --- telebot/apihelper.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/telebot/apihelper.py b/telebot/apihelper.py index e554730..d1b83a0 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -18,7 +18,6 @@ from telebot import types from telebot import util logger = telebot.logger -req_session = requests.session() proxy = None API_URL = "https://api.telegram.org/bot{0}/{1}" @@ -28,6 +27,10 @@ CONNECT_TIMEOUT = 3.5 READ_TIMEOUT = 9999 +def _get_req_session(): + return util.per_thread('req_session', lambda: requests.session()) + + def _make_request(token, method_name, method='get', params=None, files=None, base_url=API_URL): """ Makes a request to the Telegram API. @@ -47,8 +50,8 @@ def _make_request(token, method_name, method='get', params=None, files=None, bas if params: if 'timeout' in params: read_timeout = params['timeout'] + 10 if 'connect-timeout' in params: connect_timeout = params['connect-timeout'] + 10 - result = req_session.request(method, request_url, params=params, files=files, - timeout=(connect_timeout, read_timeout), proxies=proxy) + result = _get_req_session().req_session.request(method, request_url, params=params, files=files, + timeout=(connect_timeout, read_timeout), proxies=proxy) logger.debug("The server returned: '{0}'".format(result.text.encode('utf8'))) return _check_result(method_name, result)['result'] @@ -97,7 +100,7 @@ def get_file(token, file_id): def download_file(token, file_path): url = FILE_URL.format(token, file_path) - result = req_session.get(url) + result = _get_req_session().get(url) if result.status_code != 200: msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]' \ .format(result.status_code, result.reason, result.text) From 96569cbdac27a9ae4ad3405e2f1a04e5bac82829 Mon Sep 17 00:00:00 2001 From: the31k Date: Wed, 19 Jul 2017 15:44:10 +0300 Subject: [PATCH 3/3] Fix typo --- telebot/apihelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telebot/apihelper.py b/telebot/apihelper.py index d1b83a0..961b3f5 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -50,7 +50,7 @@ def _make_request(token, method_name, method='get', params=None, files=None, bas if params: if 'timeout' in params: read_timeout = params['timeout'] + 10 if 'connect-timeout' in params: connect_timeout = params['connect-timeout'] + 10 - result = _get_req_session().req_session.request(method, request_url, params=params, files=files, + result = _get_req_session().request(method, request_url, params=params, files=files, timeout=(connect_timeout, read_timeout), proxies=proxy) logger.debug("The server returned: '{0}'".format(result.text.encode('utf8'))) return _check_result(method_name, result)['result']