Самый простой длинный опрос Python

Я видел несколько тем о длинных опросах в python, но моя проблема не настолько велика, чтобы использовать некоторые дополнительные наборы, такие как торнадо и т. д. У меня есть клиент js. Он отправляет запросы на мою страницу /longpolling и ждет ответа. Как только он получает ответ или тайм-аут, он отправляет новый. Это работает хорошо. Мой обработчик /longpolling — это функция:

currentTime = datetime.datetime.now()
lastUpdate = datetime.datetime.strptime(req.GET["ts"], "%Y-%m-%dT%H:%M:%S.%f")
response = {
    "added": [],
    "updated": [],
    "deleted": []
}
while (datetime.datetime.now() - currentTime).seconds < 600:
    time.sleep(2)
    now = datetime.datetime.now()
    #query = Log.objects.filter(time__range = (lastUpdate, now))
    query = Log.objects.raw("SELECT * FROM ...log WHERE time BETWEEN %s and %s", [lastUpdate, now])
    exist = False
    for log in query:
        exist = True
        type = {
            NEW: "added",
            UPDATED: "updated",
            DELETED: "deleted"
        }[log.type]
        response[type].append(json.loads(log.data))
    if exist:
        response["ts"] = now.isoformat()
        return JsonResponse(response)
response["ts"] = datetime.datetime.now().isoformat()
return JsonResponse(response)

Каждые 2 секунды в течение 10 минут я хочу проверять наличие новых экземпляров журнала в БД, чтобы уведомить js-клиент. Я попытался вставить запись журнала вручную через phpMyAdmin, но следующий Log.objects.filter(time__range = (lastUpdate, now)) возвращает пустой QuerySet. Я копирую необработанный запрос из .query attr, он выглядит так:

ВЫБЕРИТЕ... ИЗ... ГДЕ время МЕЖДУ 05.01.2013 03:30:36 и 05.01.2013 03:45:18

Поэтому я процитировал 2013-01-05 03:30:36 и 2013-01-05 03:45:18 и выполнил этот SQL через phpMyAdmin, и он вернул мою добавленную запись. Я пытался:

запрос = Log.objects.filter(time__range = (последнее обновление, сейчас))

и

query = Log.objects.raw("SELECT * FROM ...log WHERE время МЕЖДУ %s и %s", [последнее обновление, сейчас])

и

для входа в query.iterate():

Но он всегда возвращает пустой QuerySet, но никогда не добавляет мою добавленную запись. Я думал есть какое-то кеширование, но где? Или проблема в том, что я вставляю новую запись до тех пор, пока не будет выполняться цикл while True:? Или может есть какая-то защита резьбы? Почему phpMyAdmin видит запись, а django нет? Пожалуйста, помогите мне, я застрял.


person Luft-on    schedule 05.01.2013    source источник
comment
Попробуйте использовать код django, чтобы вставить запись в журнал непосредственно перед запросом. Возможно ли, что вы случайно указываете phpMyAdmin на другую базу данных, а не на django? Разница между отладочной и производственной базами данных или что-то в этом роде?   -  person dokkaebi    schedule 05.01.2013
comment
Отличная идея вставить новую запись в журнал прямо перед этим, я постараюсь ответить. И нет, они подключены к одной и той же базе данных.   -  person Luft-on    schedule 05.01.2013
comment
Итак, если я создаю новую запись в журнале непосредственно перед запросом, я получаю ее в QuerySet, и она правильно добавляется в объект ответа и отвечает клиенту. После этого клиент отправляет новый запрос, как и ожидалось, и что теперь?   -  person Luft-on    schedule 05.01.2013
comment
Найдите симуляционный поток stackoverflow.com/questions/6887901/   -  person Luft-on    schedule 05.01.2013


Ответы (1)


Я не сталкивался с этой проблемой, поэтому не уверен. Основываясь на ответе @DanielRoseman в теме, на которую вы ссылаетесь в комментариях, вы можете сделать это:

with transaction.commit_on_success():
    query = Log.objects.raw("SELECT * FROM ...log WHERE time BETWEEN %s and %s", [lastUpdate, now])

Однако кажется более вероятным, что вам придется обернуть строки, которые вставляют ваши записи журнала в декоратор commit_on_success. Я не уверен, где в вашем коде вставлены записи журнала.

person dokkaebi    schedule 06.01.2013