1

I have a Struts2 Action class that places a JMS Fetch request for a list of Trade in a JMS Queue. This JMS Fetch message is processed by an external process and can take either a few seconds or even few minutes depending on the number of Trade files to be processed by the external task processing app.

I want to know how to handle this HTTP Request with an appropriate response. Does the client wait till the list of Trades is returned? (client (UI) has to action on it and has nothing else to do meanwhile).

The way I approached it is HTTP Request --> Struts2 Action -->

  1. Invokes a Runnable to run in a separate Thread (separate from Action class)
  2. UI waits
  3. Action class thread sleeps till runnable does it's job
  4. When Task completed, return list of Trades to UI

Flow is as follows:

  1. Place JMS Fetch Request on Queue1
  2. ExecutorService for Runnable

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

Where CClass implements runnable returning a list of Trades:

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();
}

And while this runnableis executing, I do a Thread.sleep in Action class (to let the Runnable execute in the separate Thread)

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

Problem is If I use Callable with a FutureTask and do a get() , that will be blocking till any result is returned. If I do a Runnable, I have to put Action class Thread to sleep till runnable has executed and tradeList is available.

Using Runnable approach, I am able to get couple of hundred records back to UI giving a 5 second Thread.sleep() in main Action class, but only partially constructed tradeList when thousands of records are to be fetched and shown in UI.

This is clearly Not a fail-proof approach.

Any better approach to suggest ? Please elucidate steps for processing in one complete request - response flow.

Rahul Saini
  • 2,353
  • 1
  • 16
  • 19

1 Answers1

0

Yes there is a much better approach when making a standard HTTP request (with ajax you can do other things).

You want to look at the Struts2 Execute and Wait Interceptor Which has most of the functionality you've already implemented. Also look at the token interceptor... which could be useful (it prevents duplicate requests, but doesn't provide a happy wait screen like exec and wait does).

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Quaternion
  • 10,380
  • 6
  • 51
  • 102