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

parse_response error in ThreadPoolExecutor when setting single_connection_client = True #1426

Closed
zyp-rgb opened this issue Dec 8, 2020 · 2 comments

Comments

@zyp-rgb
Copy link

zyp-rgb commented Dec 8, 2020

Version: redis-py 3.5.3, docker redislabs/rejson:1.0.4

Platform: Python 3.8.2 on mac

Description: parse_response error in threadpoolexecutor when setting single_connection_client = True

The following code reports random errors. When changing the setting single_connection_client to False, it runs okay.

import traceback
import concurrent.futures
from redis import StrictRedis

client = StrictRedis(host='redis', port=6379, db=0, decode_responses=True,
                     single_connection_client=True)

# Retrieve a single page and report the URL and contents
def redis_handler(value: int):
  a = client.zadd('test', {value: value * 2.2})
  b = client.zscore('test', value)
  c = client.set(f'test:{value}', value)
  d = client.get(f'test:{value}')
  return a, b, c, d


if __name__ == '__main__':
  # We can use a with statement to ensure threads are cleaned up promptly
  with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
      # Start the load operations and mark each future with its URL
      future_redis_handle = {executor.submit(redis_handler, i): idx for idx, i in
                       enumerate(range(100))}
      future_redis_handle.update(
          {executor.submit(redis_handler, i): idx + 100 for idx, i in
           enumerate(range(100))})

      for future in concurrent.futures.as_completed(future_redis_handle):
          idx = future_redis_handle[future]
          try:
              data = future.result()
          except Exception as exc:
            print(
              f'generated an exception: {(idx, exc, traceback.format_exc())}')
          else:
            print(f'page is bytes {(idx, data)}')

some error samples

 (45, ValueError("invalid literal for int() with base 10: '94.600000000000009'"), 'Traceback (most recent call last):\n  File "test_redis_problem.py", line 30, in <module>\n    data = future.result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 432, in result\n    return self.__get_result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result\n    raise self._exception\n  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run\n    result = self.fn(*self.args, **self.kwargs)\n  File "test_redis_problem.py", line 10, in redis_handler\n    a = client.zadd(\'test\', {value: value * 2.2})\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 2688, in zadd\n    return self.execute_command(\'ZADD\', name, *pieces, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 901, in execute_command\n    return self.parse_response(conn, command_name, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 921, in parse_response\n    return self.response_callbacks[command_name](response, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 380, in parse_zadd\n    return int(response)\nValueError: invalid literal for int() with base 10: \'94.600000000000009\'\n')

generated an exception: (51, ValueError("invalid literal for int() with base 10: 'OK'"), 'Traceback (most recent call last):\n  File "test_redis_problem.py", line 30, in <module>\n    data = future.result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 432, in result\n    return self.__get_result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result\n    raise self._exception\n  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run\n    result = self.fn(*self.args, **self.kwargs)\n  File "test_redis_problem.py", line 10, in redis_handler\n    a = client.zadd(\'test\', {value: value * 2.2})\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 2688, in zadd\n    return self.execute_command(\'ZADD\', name, *pieces, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 901, in execute_command\n    return self.parse_response(conn, command_name, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 921, in parse_response\n    return self.response_callbacks[command_name](response, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 380, in parse_zadd\n    return int(response)\nValueError: invalid literal for int() with base 10: \'OK\'\n')

generated an exception: (54, ValueError("invalid literal for int() with base 10: 'OK'"), 'Traceback (most recent call last):\n  File "test_redis_problem.py", line 30, in <module>\n    data = future.result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 432, in result\n    return self.__get_result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result\n    raise self._exception\n  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run\n    result = self.fn(*self.args, **self.kwargs)\n  File "test_redis_problem.py", line 10, in redis_handler\n    a = client.zadd(\'test\', {value: value * 2.2})\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 2688, in zadd\n    return self.execute_command(\'ZADD\', name, *pieces, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 901, in execute_command\n    return self.parse_response(conn, command_name, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 921, in parse_response\n    return self.response_callbacks[command_name](response, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 380, in parse_zadd\n    return int(response)\nValueError: invalid literal for int() with base 10: \'OK\'\n')
generated an exception: (55, AttributeError("'NoneType' object has no attribute 'readline'"), 'Traceback (most recent call last):\n  File "test_redis_problem.py", line 30, in <module>\n    data = future.result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 432, in result\n    return self.__get_result()\n  File "/usr/local/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result\n    raise self._exception\n  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run\n    result = self.fn(*self.args, **self.kwargs)\n  File "test_redis_problem.py", line 11, in redis_handler\n    b = client.zscore(\'test\', value)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 2958, in zscore\n    return self.execute_command(\'ZSCORE\', name, value)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 901, in execute_command\n    return self.parse_response(conn, command_name, **options)\n  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 915, in parse_response\n    response = connection.read_response()\n  File "/usr/local/lib/python3.8/site-packages/redis/connection.py", line 739, in read_response\n    response = self._parser.read_response()\n  File "/usr/local/lib/python3.8/site-packages/redis/connection.py", line 324, in read_response\n    raw = self._buffer.readline()\nAttributeError: \'NoneType\' object has no attribute \'readline\'\n')

@andymccurdy
Copy link
Contributor

single_connection_client is not thread safe.

@zyp-rgb
Copy link
Author

zyp-rgb commented Dec 8, 2020

single_connection_client is not thread safe.

Okay thanks

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants