Пожалуйста, подождите страницу в Spring MVC + Apache Tiles - PullRequest
1 голос
/ 02 марта 2012

Я использую Spring MVC 3 + Tiles для веб-приложения.У меня медленная работа, и я бы хотел страницу ожидания.

Существует два основных подхода к страницам ожидания, о которых я знаю:

  1. Долгоживущие запросыОтобразите и очистите бит «пожалуйста, подождите» на странице, но не завершайте запрос, пока действие не будет завершено, после чего вы можете передать остальную часть ответа с помощью некоторого JavaScript, чтобы перенаправить или обновить страницу.
  2. Немедленно вернитесь и начните обработку в фоновом потоке.Клиент опрашивает сервер (в javascript или через обновления страницы) и перенаправляет по окончании фонового потока.

(1) хорошо, так как он сохраняет действие однопоточным, но не выполняетС Tiles это кажется невозможным, поскольку каждый JSP должен полностью завершить рендеринг, прежде чем страница будет собрана и возвращена клиенту.

Итак, я начал реализацию (2).В моей реализации первый запрос запускает операцию в фоновом потоке, используя аннотацию Spring @Async, которая возвращает Future<Result>.Затем он возвращает пользователю страницу «Пожалуйста, подождите», которая обновляется каждые несколько секунд.

Когда страница «Пожалуйста, подождите» обновляется, контроллеру необходимо проверить ход фонового потока.Каков наилучший способ сделать это?

  1. Если я помещу объект Future непосредственно в Сессию, то потоки запроса опроса могут извлечь его и проверить ход потока.Тем не менее, не означает ли это, что мои сеансы не сериализуемы, поэтому мое приложение не может быть развернуто на более чем одном веб-сервере (не требуя липких сеансов)?
  2. Я мог бы установить какой-нибудь флаг состояния вSession, и фоновый поток обновит Session, когда он будет завершен.Я очень обеспокоен тем, что передача объекта HttpSession потоку без запроса приведет к сложным ошибкам при отладке.Это разрешено?Кто-нибудь может привести любую документацию в любом случае?Конечно, он прекрасно работает, когда сеансы находятся в памяти, но что если сеансы хранятся в базе данных?Что если у меня более одного веб-сервера?
  3. Я мог бы поставить какой-нибудь флаг состояния в моей базе данных, ввести идентификатор сеанса или какой-то другой аспект медленной работы.Кажется странным иметь данные сеанса в базе данных моего домена, а не в сеансе, но, по крайней мере, я знаю, что база данных является поточно-ориентированной.
  4. Есть ли другой вариант, который я пропустил?

1 Ответ

1 голос
/ 13 марта 2012

Часть вашего вопроса о Spring MVC довольно проста, поскольку проблема не имеет ничего общего с Spring MVC.Смотрите возможное решение в этом ответе: https://stackoverflow.com/a/4427922/734687

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

  • Невозможно сериализовать будущее и позволить ему перейти на второй экземпляр сервера.Поток выполняется в определенном экземпляре и поэтому должен оставаться там.Таким образом, хранение сессии не вариант.
  • Как и в примере ссылки, вы можете использовать сервис токенов.Обычно это просто HashMap, где вы можете сохранить свой объект и получить к нему доступ позже через токен (идентификатор String).Но, опять же, это работает только в том же веб-приложении, когда tokenService является одноэлементным.

Решение состоит не в том, чтобы сохранить будущее, а в состоянии работы (в работе, готово,не удалось с результатом).Даже когда сеанс запроса и исполняющие потоки находятся на разных машинах, состояние должно быть доступно и доступно для сериализации.Но как бы вы это сделали?Это может быть реализовано путем сохранения его в базе данных или в файловой системе (в приведенном выше примере вы можете проверить, доступен ли файл zip), или в хранилище ключей / значений, или в кэше, или в хранилище общих объектов (Terracota)...

Фактически, каждый пакетный фреймворк (например, Spring Batch) работает таким образом.Он хранит текущее состояние заданий в базе данных.Вы обеспокоены тем, что вы смешиваете данные домена с рабочими данными.Но большинство приложений делают.В больших приложениях есть возможность использовать два экземпляра базы данных, рабочие данные и данные домена.

Поэтому я рекомендую сохранить состояние и результат работы в базе данных.
Надеюсь, это поможет.

...