Django, используйте redis-py, чтобы зафиксировать в представлениях django - PullRequest
0 голосов
/ 05 февраля 2012

Я пытаюсь использовать redis для блокировки некоторых крупных транзакций управления Postgresql, которые есть в моем проекте.Я пока не добился успеха в моей среде разработки.

Простая версия кода будет выглядеть так:

def test_view(request):
  connec = redis.Redis(unix_socket_path='/tmp/vgbet_redis.sock')
  if not connec.setnx('test', ''):
    print 'Locked'
  else:
    time.sleep(5) #Slow transaction
    connec.delete('test')
    print 'Unlocked'
  return render_to_response("test.html")

Если я открою две вкладки этого представления, перваяодин отпечаток разблокирован через 5 секунд, затем второй отпечаток разблокирован через 10 секунд.Похоже, они синхронны, что не имеет никакого смысла для меня.

Редактировать: Я попытался установить Apache и Gevent, и я получил точно такие же результаты.

Так что, я думаю, что с django + redis действительно что-то не так, и мой код действительно неправильный.

Любая помощь будет великолепна.

Edit2: Я только что попробовал с django-redis, используя redis в качестве кэша.

CACHES = {
  'default': {
    'BACKEND': 'redis_cache.RedisCache',
    'LOCATION': '/tmp/vgbet_redis.sock',
    'OPTIONS': {
      'DB': 1,
      'PASSWORD': None,
      'PARSER_CLASS': 'redis.connection.HiredisParser'
    },
  },
}

И у меня все еще тот же результат, если я открываю две вкладки в своем браузере.Второй вид блокируется на 5 секунд, как будто все синхронно.

from django.core.cache import cache
def test_view(request):
  if cache.get('test') != None:
    print 'Locked'
  else:
    cache.set('test', '', 60)
    time.sleep(5) #Slow transaction
    cache.delete('test')
  return render_to_response("test.html")

Если я открою два терминала, у меня не возникнет проблем при чтении и записи в redis.Поэтому я действительно не понимаю, почему я не могу использовать кеш в представлениях.

Ответы [ 2 ]

2 голосов
/ 05 февраля 2012

Пара вещей для проверки:

  • Сервер разработки Django по умолчанию является однопоточным, поэтому может обрабатывать только один запрос за раз.Самый простой способ проверить это - дважды запустить сервер разработки на разных портах (например, ./manage.py runserver 8080 и ./manage.py runserver 8081).
  • Если вы вообще используете базу данных SQL, то может блокировать транзакцию.Эти точные представления, которые вы используете?Или вы что-то делаете с моделями?
  • Вы упомянули об использовании gevent - вы были уверены, что позвоните from gevent import monkey; monkey.patch_all(), чтобы обезьяна все исправила?Кроме того, как у вас работает сервер с Gevent?
0 голосов
/ 05 февраля 2012

Основной причиной моей проблемы было то, что я использовал две вкладки в своем браузере. Если я использую два браузера или два разных IP, мой код работает асинхронно (с gevent и apache, а не с runserver, но это не удивительно).

Я думаю, что есть что-то вроде: если уникальный сеанс запрашивает одно и то же представление несколько раз, они обслуживаются синхронно. Я не знаю, связано ли это с сервером или Django. Я не могу найти ничего подобного в документации. Если кто-нибудь знает, мне было бы очень интересно понять эту последнюю часть.

...