Выполнение длительной задачи из Tapestry с использованием уже существующей службы EJB

У меня следующая ситуация.

У меня есть веб-сайт, написанный на Tapestry. На одной из страниц мне нужно создать довольно большой документ Excel или PDF (около 20 МБ). Теперь, поскольку весь процесс требует времени, я прошу своего пользователя немного подождать.

Однако, когда я попытался проверить верхние пределы, я заметил, что все мое приложение (не только веб-часть) зависает, потому что генерация съедает все ресурсы, а остальная часть веб-сайта и приложения перестает отвечать на запросы.

Вот поток, как я делал это до сих пор.

  1. Пользователь нажимает кнопку, чтобы запросить файл на странице
  2. Данные извлекаются из базы данных (эта часть выполняется довольно быстро)
  3. Данные передаются в сервис Tapestry, который их подготавливает (ничего особенного, тоже быстро)
  4. Подготовленные данные отправляются в службу EJB, которая создает и развертывает посетителя, который создает файл excel/pdf.
  5. InputStream созданного файла передается в Tapestry, который оборачивает его в StreamResponse и предлагает загрузить

Что было бы подходящим способом справиться с этой проблемой?

Могу ли я использовать Tapestry ParallelExecutor из какого-нибудь моего сервиса Tapestry таким образом?

Future<InputStream> future = executor.invoke(new Invokable<InputStream>() { ... });

Моя главная цель — чтобы приложение и сайт продолжали работать, чтобы они не зависали.

Заранее спасибо.


person ioreskovic    schedule 09.10.2014    source источник


Ответы (1)


Взгляните на демонстрацию progresslink из гобелена. Это может дать вам некоторое вдохновение для опроса длительной/асинхронной задачи в гобелене.

person lance-java    schedule 09.10.2014
comment
Ну, моя задача на самом деле не должна быть асинхронной, я не могу просто нажать кнопку и забыть об этом. Мне нужно дождаться результата (файла) и что-то с ним сделать. - person ioreskovic; 09.10.2014
comment
Как я уже сказал, это было для вдохновения. Вы можете расширить интерфейс ProgressTask и добавить метод getResult(). Этот метод вызывается только тогда, когда getProgress() достигает 1 (100%). В вашем случае getResult() вернет PDF (массив байтов), и вы можете остановить опрос и перенаправить в PDF. - person lance-java; 09.10.2014
comment
Обратите внимание, ProgresssTaskManagerImpl удаляет задачи сразу после их завершения. Возможно, вам придется где-то сохранить результат (ConcurrentMap) перед удалением. - person lance-java; 09.10.2014