Как я могу обнаружить прерванное соединение в Django? - PullRequest
4 голосов
/ 16 мая 2011

У меня есть представление Django, которое выполняет довольно тяжелую обработку и возвращает результат примерно 20-30 секунд.

Иногда пользователь заканчивает тем, что закрывает окно браузера (разрывая соединение) перед запросомзавершает - в этом случае я хотел бы иметь возможность обнаружить это и перестать работать.Работа, которую я выполняю, доступна только для чтения в базе данных, поэтому с транзакциями проблем не возникает.

В PHP функция connection_aborted делает именно это.Доступна ли эта функция в Django?

Вот пример кода, который я хотел бы написать:

def myview(request):
    while not connection_aborted():
        # do another bit of work...
        if work_complete:
            return HttpResponse('results go here')

Спасибо.

Ответы [ 3 ]

1 голос
/ 17 мая 2011

Я не думаю, что Django предоставляет это, потому что это в принципе не может. В большей степени, чем сам Django, это зависит от того, как Django взаимодействует с вашим веб-сервером. Все это зависит от вашего программного стека (который вы не указали). Я не думаю, что это даже часть протоколов FastCGI и WSGI!

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

0 голосов
/ 17 мая 2011

Итак, у вас есть представление AJAX, которое выполняет запрос, который занимает 20-30 секунд для обработки запрошенного в фоновом режиме отображаемой страницы, и вы беспокоитесь о потраченных впустую ресурсах, когда кто-то отменяет загрузку страницы.

Я вижу, что у вас есть варианты в трех широких категориях:

  1. Живите с этим.Улучшите ситуацию, кэшируя результаты на случай, если пользователь вернется.
  2. Сделайте это быстрее.Бросьте больше места во время / пространство компромисса.Вести промежуточные таблицы.Пересчитайте все это и т. Д.
  3. Сделайте что-нибудь умное с браузером, быстро опрашивая "Готово ли это еще?"запрос и сервер отменяет запрос, если он не получает ворчание в интервале * 2 или подобное.Если вы действительно сообразительны, вы можете вернуть прогресс / ETA к надгробиям.Тем не менее, это может не иметь особенно полезного поведения, когда система находится под нагрузкой или доступ к вашему сайту осуществляется по ограниченной полосе пропускания.

Я не думаю, что вам следует выбирать вариант 3, поскольку это увеличивает сложность ииспользование ресурсов не сильно увеличивает прибыль.

0 голосов
/ 16 мая 2011

Этот connection_aborted метод в PHP не делает то, что вы думаете, что он делает.Он сообщит вам, если клиент отключил , но , только если буфер был очищен, то есть какой-то ответ отправляется с сервера обратно клиенту.Версии PHP даже не будут работать так, как вы написали выше.Вам нужно добавить вызов к чему-то вроде flush в вашем цикле, чтобы сервер попытался отправить данные.

HTTP - это протокол без сохранения состояния.Он предназначен , чтобы не зависеть ни от клиента, ни от сервера.В результате состояние любого из них известно только при создании соединения, и это происходит только тогда, когда есть данные для отправки тем или иным способом.

Лучше всего делать так, как предложил @MattHсделайте это с помощью AJAX, и, если хотите, вы можете интегрировать что-то вроде Node.js, чтобы выполнять «проверки» клиента во время обработки.Однако, как правильно это настроить, выходит за рамки моей компетенции.

...