/** * Uses <code>generator</code> to generate a command, execute it, then send the appropriate * response. * * <p>The following steps occur: * * <ul> * <li>The command and its assigned command runner are generated by the generator * <li>The command is scheduled to execute on the command runner * <li>The method blocks until the command is executed, or the timeout occurs, (the timeout * period is a servlet configuration parameter) * <li>When execution is complete, a response is sent using {@link * JMSCommandGenerator#sendResponse(HttpServletResponse)} * </ul> * * @param generator the selected <code>JMSCommandGenerator</code> * @param request a <code>HttpServletRequest</code> * @param response a <code>HttpResponse</code> * @throws ServletException if there is a problem accessing the servlets <code>HJBRoot</code> * @throws IOException if a problem occurs while writing the response */ protected void handleUsingSelectedGenerator( JMSCommandGenerator generator, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { generator.generateCommand(request, getRoot()); JMSCommand generatedCommand = generator.getGeneratedCommand(); synchronized (generatedCommand) { HJBApplication.CommandTimeoutTask timeIsUp = new HJBApplication.CommandTimeoutTask(); try { // Schedule the command with the command runner, then start a // timer to time it out generator.getAssignedCommandRunner().schedule(generatedCommand); getTimeoutTimer().schedule(timeIsUp, getCommandTimeout()); while (!generatedCommand.isComplete()) { // N.B. for this to work, JMSCommand#setComplete MUST be // synchronized (and they all are! see // BaseJMSCommand#completed) generatedCommand.wait(getCommandTimeout()); if (timeIsUp.barIsClosed()) { handleCommandExecutionWasTimedOut(generator, response, generatedCommand); return; } } } catch (InterruptedException e) { handleExecutionThreadWasInterrupted(response, generatedCommand, e); return; } finally { timeIsUp.cancel(); } } generator.sendResponse(response); }
protected void handleCommandExecutionWasTimedOut( JMSCommandGenerator generator, HttpServletResponse response, JMSCommand generatedCommand) throws IOException { // Instruct the command runner to ignore the command // The command runner **will** log the instruction // If the command has not run yet (i.e, the // timeout occurred while the command was waiting to be // run), the command runner will discard the ignored // command // Otherwise, at least both HJB and the HTTP user agent // will have a message showing that something went // wrong... generator.getAssignedCommandRunner().ignore(generatedCommand); String message = strings() .getString( HJBStrings.COMMAND_EXECUTION_TIMED_OUT, generatedCommand.getDescription(), new Long(getCommandTimeout())); LOG.error(message); HJBException fault = new HJBException(message); fault.fillInStackTrace(); new RuntimeExceptionHandler().sendHJBFault(response, fault); }