Chapter 22. Asynchronous Request Processing Framework

Table of Contents

Introduction
How it works
The Big Picture
A Real World Example
The Details
Implementing Your Own Async Process
Conclusion
Contributors

Note

If you find this EDG documentation helpful please consider DONATING! to keep the doc alive and current.

 Maintainer:David Lloyd

Introduction

There are times when you need to process a task that is going to take a long time. Examples are processing credit cards, performing reporting tasks, retrieving a user record from remote databases. For each of these items, it is desirable to give the user immediate feedback of some sort, while the task continues. Or if the task has progressive results, it would be even more desirable to display those results as they become available. Imagine how much nicer it would be to work with DBCreate if you could see the tables being created on the browser screen instead of waiting for 30 seconds before you saw any result at all!

This is where the Async Processing Framework comes into being. Although the default setup uses a servlet to provide lifecycle events, it is certainly not restricted to a servlet environment. The interfaces provided are quite generic and can be adapted to nearly any situation such as JMS message queuing, RMI dispatching to remote machines, or even command line multithreading tasks.

How it works

The Big Picture

Let's talk about the basic flow of events on how the Async process model works. Below is a sequence diagram showing a simplistic view of the actions.

So here's a step by step walkthrough of the diagram:

  1. [Factory method] The Controller wants to have a process performed asynchronously. So it calls AsyncProcessorFactory.getAsyncProcessor() to get an instance of the processor.

  2. The Controller then constructs an object that implements the AsyncProcess interface and hands that to the processor by calling AsyncProcessor.addToQueue()

  3. The AsyncProcessor queues the process and returns an AsyncTicket object. Think of AsyncTicket as a claim ticket.

  4. When the AsyncProcessor has available slots, it called the queued object's process() method.

  5. After a period of time, the Controller will want to see how its AsyncProcess is doing. So it calls AsyncProcessor.getStatus() by giving the AsyncProcessor the AsyncTicket it received originally by calling addToQueue()

  6. The AsyncProcessor now checks the status of the running process. It then builds an AsyncProcessResult object and returns it to the controller.

  7. If the status of the process was that it was finished, the AsyncProcessor adds the result of the process into the AsyncProcessResult object and then removes all references to that particular ticket. Any future claims on the ticket will throw an Exception.

  8. The controller then, based upon the object's status either renders the Status object or the Result object. [Or possibly both!].

  9. If an exception was thrown by the process, it is stored in the AsyncProcessResult object too, and the controller can then decide what to do with the exception.

Now let's reiterate what is done strictly from the controller standpoint. This is important as it will affect the general flow of your app while the process is running:

  1. The controller gets the async processor and queues the process.

  2. The controller checks to see if the process is done.

  3. If the process is not done, then the controller sends the client to a status page that automatically refreshes after, for example, 5 seconds. The ticket should be saved in the user's session.

  4. Now that the page refreshes, the controller once again checks to see if the process is done. If not, repeat the previous step.

  5. If the process is done, then retrieve the result and display the result

  6. If the process threw an exception, then the exception should be handled appropriately.

A Real World Example

Time to put this in a plain English use case. Joe wants to order "Awesome Book" from Bookazon.com. He's navigated the checkout system and now wants to complete his order. Bookazon's back end for credit card processing is a bit old, however. It has a bank of modems hooked to a serial port back to the processing servers. Each time a card is validated, one of the modems has to dial out to the validation server and validate the results. Obviously this is going to take a few seconds, and we all know what fidgety end users do, especially when "Awesome Book" and their credit card is on the line!

This is where the async processing system can come to the rescue. "Mack Programmer" implements the entire dialing and validation sequence in a AsyncProcess implemented object. So what happens is the following sequence of events. Each physical even is cross-referenced to a step in the previous list.

  1. The checkout controller creates an order processor process and submits it to the processing queue. [Step 1]

  2. Since the dialout takes a long time, we don't even try to see if the process is complete right after it has been submitted. [Skip step 2] So instead we display a fancy "Your order is being processed, please please please please don't hit the back button!" page. Instead of sitting there fidgeting thinking of hackers and all that proverbial trash, Joe is nicely occupied with the message and fancy Javascript animations on the page. Much less temptation to hit the back button! [Step 3]

  3. After a couple of seconds, the browser refreshes to see how the process is going. Since dialing takes a while, perhaps we'll want to have alternate screens that come up for more eye candy... [Step 4]

  4. After a couple of refreshes, the authorization code finally comes through! We send Joe onto to the 'success' page and display his order. Joe is happy, we're happy. [Step 5]

  5. If Joe blew it on the credit card number, then we can show the authorization failed message and prompt for a re-input of the card. Joe now may not be happy, but we're still happy because Joe didn't hit the back button while processing was taking place! [Step 6]

The Details

As you can see, there are quite a few objects interacting here to make this whole dance take place. The following is a UML static structure diagram:

The color coding of the UML diagram is this:

  • Yellow: These are the interfaces that you will be interacting with.

  • Green: Concrete classes you will use. In this case, it is mainly the static factory method in the Processor factory class tat is used

  • Blue: Your own processor class that you will need to implement

  • White: Expresso default implementations of the interfaces. You will not directly instantiate or interact with these objects themselves. They are mainly there for reference and assistance for spelunking the depths of Expresso code

Implementing Your Own Async Process

Now that plenty of theory has been covered, let us turn to the task of creating an asynchronous object.

Details TODO

Conclusion

Contributors

The following persons have contributed their time to this chapter:

  • Mike Rimov

Note

Was this EDG documentation helpful? Do you wish to express your appreciation for the time expended over years developing the EDG doc? We now accept and appreciate monetary donations. Your support will keep the EDG doc alive and current. Please click the Donate button and enter ANY amount you think the EDG doc is worth. In appreciation of a $35+ donation, we'll give you a subscription service by emailing you notifications of doc updates; and donations $75+ will also receive an Expresso T-shirt. All online donation forms are SSL secured and payment can be made via Credit Card or your Paypal account. Thank you in advance.

Copyright © 2001-2004 Jcorporate Ltd. All rights reserved.