Длительный Ajax-запрос калитки

У меня иногда возникают длительные AJAX-запросы в моем приложении Wicket. Когда это происходит, приложение практически невозможно использовать, поскольку последующие запросы AJAX ставятся в очередь для синхронной обработки после текущего запроса. Я хотел бы, чтобы запрос завершался через определенный период времени независимо от того, был ли возвращен ответ (у меня есть требование пользователя, что если это произойдет, мы должны представить пользователю сообщение об ошибке и продолжить). Это ставит два вопроса:

  1. Есть ли способ указать время ожидания, специфичное для AJAX или всех запросов AJAX?
  2. Если нет, есть ли способ убить текущий запрос?

Я просмотрел файл wicket-ajax.js и не вижу никаких упоминаний о тайм-ауте запроса.

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

Спасибо!


person Michael Krauklis    schedule 04.03.2010    source источник


Ответы (2)


Я думаю, что это не поможет вам позволить клиенту «отменить» запрос. (Однако это может сработать.)

Дело в том, что сервер занят обработкой запроса, который больше не требуется. Если вы хотите тайм-аут таких операций, вы должны были реализовать тайм-аут на стороне сервера. Если операция занимает слишком много времени, сервер прерывает ее и возвращает некоторое значение ошибки в результате Ajax-запроса.

Что касается вашей проблемы с очередями: вы можете использовать асинхронные запросы, несмотря на синхронные. Это означает, что клиент сначала отправляет запрос на запуск долго выполняющегося процесса. Этот запрос немедленно возвращается. Затем клиент периодически опрашивает сервер и спрашивает, завершился ли процесс. Эти запросы опроса также немедленно возвращаются, говоря, что процесс все еще выполняется или что он завершился с определенным результатом.

person Wolfgang    schedule 06.03.2010
comment
Спасибо Вольфганг. Я должен был упомянуть, что мы обрабатываем модели асинхронно для вызовов, которые, по нашему мнению, могут выполняться долго (отчеты, большие наборы данных и т. д.), но мы пытаемся решить проблему, когда иногда и неожиданно запрос занимает много времени по непредвиденным причинам. Иногда это происходит из-за проблем с БД (переиндексация, плохой дизайн запроса и т. д.), а иногда из-за того, что запросы сторонних сервисов занимают больше времени, чем ожидалось. В идеале мы должны инкапсулировать все эти вызовы асинхронно, но на данном этапе жизненного цикла программного обеспечения это просто невозможно. Спасибо за ваш вклад. - person Michael Krauklis; 08.03.2010

Неудачное решение: после заданного setTimeout я убиваю активные транспорты и перезапускаю канал, который обрабатывает все на стороне клиента. Я избегал конфликтов запросов, привязывая каждый к идентификатору и проверяя его по глобальной ссылке, которая увеличивается каждый раз, когда делается запрос и каждый раз, когда запрос завершается.

 function longRunningCallCheck(refId) {
    // make sure the reference id matches the global id.
    // this indicates that we are still processing the
    // long running ajax call.
    if(refId == id){
        // perform client processing here

        // kill all active transport layers
        var t = Wicket.Ajax.transports;
        for (var i = 0; i < t.length; ++i) {
            if (t[i].readyState != 0) {
                t[i].onreadystatechange = Wicket.emptyFunction;
                t[i].abort();
            }
        }

        // process the default channel
        Wicket.channelManager.done('0|s');
    }
 }

К сожалению, это по-прежнему оставило PageMap заблокированным, и все последующие вызовы ожидают завершения запроса на стороне сервера.

Мое решение на данный момент состоит в том, чтобы вместо этого предоставить пользователю возможность выйти из системы с помощью BookmarkablePageLink (который создает экземпляр новой страницы, таким образом, не имея конкуренции на PageMap). Определенно не оптимально.

Любые лучшие решения более чем приветствуются, но это лучшее, что я мог придумать.

person Michael Krauklis    schedule 05.03.2010
comment
+1 за распознавание и публикацию неудачной попытки. Если ничего другого, это больше знаний. - person Matt; 09.03.2010
comment
не знаю, поможет ли это (в данный момент я взламываю ajax + wicket): Wicket.Throttler(true) может помочь на время ожидания (см. wicket-autocomplete.js из расширения wicket), а затем вы можете снова попытать счастья с AjaxLazyLoadPanel :-) для фоновой задачи (или посмотрите индикатор прогресса от wicketstuff) - person Karussell; 09.09.2010