Struts2 JMS-запрос обрабатывает длительный процесс

У меня есть класс действий Struts2, который размещает запрос JMS Fetch для списка сделок в очереди JMS. Это сообщение JMS Fetch обрабатывается внешним процессом и может занять несколько секунд или даже несколько минут в зависимости от количества файлов Trade, которые должны быть обработаны внешним приложением для обработки задач.

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

Я подошел к этому так: HTTP-запрос --> Действие Struts2 -->

  1. Вызывает Runnable для запуска в отдельном потоке (отдельно от класса Action)
  2. Пользовательский интерфейс ждет
  3. Поток класса действий спит, пока runnable не выполнит свою работу
  4. Когда задача завершена, верните список сделок в пользовательский интерфейс.

Поток выглядит следующим образом:

  1. Поместите запрос на выборку JMS в Queue1
  2. ExecutorService для Runnable

    CClass cclass = new CClass();
    final ExecutorService execSvc = Executors.newFixedThreadPool(1);
    execSvc.execute(cclass);
    

Где CClass реализует runnable, возвращающий список сделок:

List<Trade> tradesList = new ArrayList<Trade>();

@Override
public void run() {

    while (true) {
        try {
            Message message = msgConsumer.receive();  // SYNCHRONOUS / NO MDB
            if (message == null){
                break;
            }
            if (message instanceof TextMessage) {
                TextMessage txtMessage = (TextMessage) message;
                Trade trade = TradeBuilder.buildTradeFromInputXML(txtMessage);
                if (trade != null) {
                    tradesList.add(trade);   // tradeList is a CClass class variable 
                }
            }
        } catch (JMSException e) {
            logger.error("JMSException occurred ", e);
        }
    }
    closeConnection();
}

И пока этот runnable выполняется, я делаю Thread.sleep в классе Action (чтобы Runnable выполнялся в отдельном потоке)

 // In Action class    
  try {
        Thread.sleep(5000); // some time till when the runnable will get executed
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    execSvc.shutdown();

Проблема в том, что если я использую Callable с FutureTask и выполняю get() , это будет блокироваться до тех пор, пока не будет возвращен какой-либо результат. Если я делаю Runnable, я должен перевести поток класса Action в спящий режим до тех пор, пока runnable не будет выполнен и не будет доступен tradeList.

Используя подход Runnable, я могу вернуть пару сотен записей обратно в пользовательский интерфейс, предоставляя 5-секундный Thread.sleep() в основном классе Action, но только частично сконструированный tradeList, когда тысячи записей должны быть извлечены и показаны в пользовательском интерфейсе.

Это явно не отказоустойчивый подход.

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


person Rahul Saini    schedule 04.04.2012    source источник


Ответы (1)


Да, есть гораздо лучший подход при выполнении стандартного HTTP-запроса (с помощью ajax вы можете делать другие вещи).

Вы хотите просмотреть Struts2 Выполнение и ожидание перехватчика, который имеет большую часть функций, которые вы уже реализовали. Также посмотрите на перехватчик токенов... который может быть полезен (он предотвращает дублирование запросов, но не обеспечивает экран счастливого ожидания, как это делают exec и wait).

person Quaternion    schedule 04.04.2012