Вот проблема
Пользователь веб-приложения предприятия выполняет задачу, которая приводит к долгому (очень длинному) запросу базы данных (или другой долгой обрабатывающей интенсивной задаче)
Проблемы:
Существует несколько решений, которые я предложил, но я не уверен, что знаю, который лучше (во всех аспектах, производительности, лучшей практике, элегантности и пригодности для обслуживания), и я хотел бы знать то, что Ваше рекомендуемое решение, и если существует решение, которое я пропустил? (вероятно, да, и многие)
Плохое решение: используйте поток запроса в качестве рабочего потока, сохраните состояние прогресса на сессии, имейте проверку вызова Ajax состояние (на сессии) в другом параллельном запросе
Компромиссное решение: создайте свой собственный пул потоков, обработайте контролирующий поток, рабочий поток и заботьтесь о кластеризации путем синхронизации состояний или в distrubuted транзакционном кэше или в персистентном устройстве хранения данных. это выпускает запрос, но creats распараллеливает сервер приложений, не знает и не закроется в неразвертывании. До Вас для завершения работу потоков в очевидном способе, и всегда существует шанс, Вы закончите тем, что пропустили что-то. Это не способ J2EE сделать это также.
Решение J2EE: используйте JMS для асинхронной задачи, это - то, для чего это является ment
решение для Spring: используйте пакет Spring
То, что Вы сделали бы / сделало в Ваших проектах? Что другие решения Вы знаете? то, которое из тех я отметил выше, является победителем по Вашему мнению?
Я бы сделал комбинацию твоего так называемого "плохого решения" и "решения j2ee":
Хитрость заключается в совпадении пары запрос/ответ. Я бы сделал это так:
NULL
. Также передайте этот идентификатор в пользовательский интерфейс.NULL
.Это чистое и хорошо абстрагированное значение из любого конкретного домена. Чисто техническое решение.
Даже если вам не нравится опрос, HTTP по своей природе является апатридом, и я думаю, что таким образом опрос происходит только через четко определенные промежутки времени.
В любом случае, я реализовал систему именно с таким паттерном, и она работает просто отлично...
.Покажите пользователю сообщение о том, что "Ваш запрос принят и обновление займет час"
Вы создаете таблицу, в которой хранятся все эти транзакции и обрабатываете их пакетно на сервере.
Пользователю не придется долго ждать, и он будет рад увидеть это сообщение. Как только транзакция будет обработана, вы можете отправить подтверждение по электронной почте.
Это лучшее решение, на мой взгляд.
.Решение, которое я использовал раньше, включает Jetty Cometd вместо AJAX. Основное различие между Ajax и Cometd заключается в том, что Cometd может использовать больше модели pub/sub - клиент (в данном случае web-браузер) подписывается на издателя (ваше приложение) и приложение выталкивает обновления и уведомления в web-браузер, как в случае с ajax моделью постоянного опроса сервера web-браузером. Вы можете использовать решение Cometd, даже если вы не используете jetty - вы можете бросить банку с приставкой в папку lib вашего соответствующего веб-сервера, и вы должны быть готовы к работе
.Как долго выполняются эти запросы?
Если вы говорите об истекающих сессиях, то, возможно, лучше, чтобы пользователь не ждал их. Всегда будет раздражать, когда пользователь будет ждать 20 минут, пикируя каждый раз так часто во вкладке этого запроса.
Итак, если речь идет о действительно длинных запросах, возможно, лучше изменить подход к пользовательскому интерфейсу и заставить пользователя "заказать" запрос, который он (она) позже вернётся к просмотру, или даже получит уведомление по почте, когда он будет готов.
В таком случае запрос должен быть подготовлен в БД и кэширован в отдельной таблице. То есть, я бы заставил веб-сервер работать один раз, чтобы зарегистрировать запрос, иметь задачу БД или отдельный процесс/сервер подготавливал запросы по запросам и уведомлял пользователя, а затем заставил бы веб-сервер отображать их, когда пользователь вернется за результатами.
.