LoopExit: "Эта операция блокирует навсегда" с Redis в качестве кеша на Django
Я работаю с Django 1.7 python 2.7. В Джанго у меня есть несколько функций. Одна функция готовит необходимую информацию и сохраняет ее в Redis. После этого другая функция запускается несколько раз асинхронно, получает информацию от Redis, вычисляет некоторые данные и возвращает клиенту. Функция запускается из браузера, и у меня появляются следующие ошибки:
user_names = json.loads(cache.get(user_id))
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/django_redis/cache.py", line 25, in _decorator
return method(self, *args, **kwargs)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/django_redis/cache.py", line 73, in get
client=client)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/django_redis/client/default.py", line 215, in get
value = client.get(key)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/client.py", line 863, in get
return self.execute_command('GET', name)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/client.py", line 565, in execute_command
return self.parse_response(connection, command_name, **options)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/client.py", line 577, in parse_response
response = connection.read_response()
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/connection.py", line 569, in read_response
response = self._parser.read_response()
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/connection.py", line 224, in read_response
response = self._buffer.readline()
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/connection.py", line 162, in readline
self._read_from_socket()
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/redis/connection.py", line 120, in _read_from_socket
data = self._sock.recv(socket_read_size)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/gevent/_socket2.py", line 253, in recv
self._wait(self._read_event)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/gevent/_socket2.py", line 152, in _wait
self.hub.wait(watcher)
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/gevent/hub.py", line 559, in wait
result = waiter.get()
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/gevent/hub.py", line 800, in get
return self.hub.switch()
File "/home/user/.virtualenvs/Django/local/lib/python2.7/site-packages/gevent/hub.py", line 538, in switch
return greenlet.switch(self)
LoopExit: ('This operation would block forever', <Hub at 0x7f3b65bb0370 epoll pending=0 ref=0 fileno=27>)
Из пяти раз функция выполняется 3-4 раза или может выполняться все 5 раз.
UPD (добавить код). Мой код примерно такой:
import json
from django.core.serializers.json import DjangoJSONEncoder
from .models import users, reports
from .helpers import FILTERS
KEYS = ['query_1', 'query_2', 'query_3', 'query_4', 'query_5']
def initial_data(request):
context = {}
user_names = users.objects.filter(**FILTERS).values_list('user_name', 'user_last_name', 'user_email')
user_names = {email: {' '.join((name, last_name)) for name, last_name, email in user_names}}
user_id = str(request.user.id)
try:
cache = get_cache('default')
cache.set(user_id, json.dumps(user_names, cls=DjangoJSONEncoder))
except:
context['errors'] = ["Can't get access to the Redis"]
else:
context['errors'] = []
return HttpResponse(json.dumps(context, cls=DjangoJSONEncoder), content_type="application/json")
def data(request):
context = {}
key = request.GET['key']
user_id = str(request.user.id)
cache = get_cache('default')
user_names = json.loads(cache.get(user_id))
if key == 'query_1':
emails = list(user_names.keys())[0:9]
if key == 'query_2':
emails = list(user_names.keys())[10:19]
if key == 'query_3':
emails = list(user_names.keys())[20:29]
if key == 'query_4':
emails = list(user_names.keys())[30:39]
if key == 'query_5':
emails = list(user_names.keys())[40:49]
result = reports.objects.filter(user_email__in=emails).values_list('date', 'text', 'user_email')
for date, text, email in result:
context[email] = [user_names[email], date, text]
return HttpResponse(json.dumps(context, cls=DjangoJSONEncoder), content_type="application/json")
В функции initial_data
Я собираю информацию о пользователях из базы данных, которая необходима для фильтрации отчетов и сохранения ее в Redis. ИП знает все KEYS
('query_1', 'query_2', 'query_3', 'query_4', 'query_5') и асинхронно отправлял запрос по одному ключу за раз в функцию data
,