Interactions between software components can be synchronous or asynchronous. An interaction is synchronous if the caller of a method must wait for the method's work to complete before the caller can continue its processing. An interaction is asynchronous if the called method returns immediately, allowing the caller to continue its processing without delay.
An asynchronous interaction typically initiates a computation but does not wait for the result to be available, which means it must provide some way for the caller to obtain the results of the computation at a later time. The distributed nature of web applications introduces unpredictable and sometimes very long latencies, which means it may take an operation a long time to complete. If a business process executing over the network involves human interaction at the back end, an operation can take on the order of days. If all interactions over the web were synchronous, clients with pending operations could consume resources on their host systems for unacceptably long periods of time.
WebLogic Workshop provides tools that make it easy for you to build asynchronous web services and Java controls that don't require clients to block execution while waiting for results. WebLogic Workshop provides multiple approaches for returning results to your web services' and Java controls' clients; you can choose the one that best suits each situation.
Getting Started: Using Asynchrony to Enable Long-Running Operations
WebLogic Workshop provides tools that make it easy for you to build asynchronous web services and asynchronous Java controls. This section introduces the concept of a callback, which is one of the critical design components when building an asynchronous web service or Java control, and describes the requirements for using callbacks. In addition, this section describes how to add buffering to methods and callbacks to enable the handling of high-volume traffic.
Introduction to Asynchronous Java Controls
Before reading this topic, you should understand the general concepts related to asynchronous interfaces. To learn about asynchronous interfaces, see Introduction to Asynchronous Interfaces.
In WebLogic Workshop, Java controls can have the same asynchronous behavior as web services. However, the behavior of a Java control is dependent on the nature of the Java control's client.
To understand this concept, think about how Java controls are used by their clients: the client is a web service, a page flow or another Java control and the Java control instance is declared as a member variable of the client. This means that the Java control instance cannot have a lifetime that exceeds that of its client.
Using Java Controls from Web Services
WebLogic Workshop web services can be conversational. Conversations allow you to control the lifetime of an instance of a web service. Since the lifetime of member variables of a web service is the same as the lifetime of the instance of the web service, Java controls references by a web service also have the same lifetime. Therefore, if a Java control's client is a web service the Java control may freely use callbacks to communicate with its client because the client is guaranteed to exist if the Java control instance exists. Note that the Java control's client must still explicitly implement handlers for each Java control callback it wishes to receive.
To learn more about conversations and WebLogic Workshop web services, see Designing Conversational Web Services.
Using Java Controls from Page Flows
A page flow may also declare a Java control member variable. However, page flows ultimately represent web pages, and web pages operate on a strictly request-response basis from the user's browser. There is no way to "push" information to the browser with a browser-originated request initiated by or on behalf of the user. Since data cannot be "pushed" to the browser, it doesn't make sense to "push" data to a page flow, which is what a callback would represent. Therefore, page flows are not capable of receiving callbacks from a Java control.
However, it is possible to use an intermediary Java control with a polling interface to provide an "adapter" between a page flow and a Java control that uses callbacks. See Example 2, below, but substitute page flow for the non-conversational web service in the example.
With page flows, the limiting issue is not conversational lifetime as it is for web services. The limiting issue with page flows is the inability to "push" information out to the browser. The scenario in Example 2 below hides the "push" (the callback) in Java control A, which presents only a "pull" interface to its client.
To learn more about polling interfaces, see Using Polling as an Alternative to Callbacks.
Using Java Controls from Other Java Controls
Whether callbacks can be sent form one Java control to another depends on the ultimate client at the end of the chain of Java controls. This is probably best illustrated by examples:
Example 1
Assume that you have a conversational web service that uses Java control A, which in turn uses Java control B. The lifetime of the Java control A instance is the same as the lifetime as the web service's conversation, and the lifetime of the Java control B instance is the same as that of Java control A (everything has the same lifetime: that of the web service's conversation). In this situation Java control B may use callbacks to communicate with Java control A, and Java control A may use callbacks to communicate with the web service.
Example 2
Assume the same situation as Example 1, but with a non-conversational web service. Since the web service is non-conversational, the lifetime of an instance of the web service spans only a single invocation of any of the web service's methods. Therefore the lifetime of the web services member variables, including its instance of Java control A, is the same, and the lifetime of the member variables of Java control A, including Java control B, is also the same. Java control A cannot use callbacks to the web service because once the web service method completes Java control A no longer exists. However, if Java control A were to provide a polling interface to be used by the web service, then Java control B may use callbacks to communicate with Java control A. Here is a scenario:
1. A web service client calls a web service method and an instance of the web service is created.
2. An instance of Java control A is created because it is a member variable of the web service.
3. An instance of Java control B is created because it is a member variable of Java control A.
4. The web service method calls the "start request" method of a polling interface provided by Java control A.
5. The "start request" method of Java control A calls a "start request" method of Java control B that will eventually result in a callback to Java control A.
6. The web service method repeatedly calls a "check status" method of Java control A. The method returns false until the result is available.
7. When Java control B's work is completed, it calls a callback of Java control A.
8. The callback handler of Java control A stores the result.
9. The next time the web service calls the "check status" method of Java control A, it returns true.
10. The web service calls a "get result" method on Java control A.
11. The web service returns the result as the return value of the method invoked in step 1.
12. The web service instance is released, causing the release of the instance of Java control A and in turn the release of the instance of Java control B.
Note that step 6 is not advisable if Java control B's work will take a long time. The initial request to the web service in step 1 may time out.
Designing Conversational Web Services
A single web service may communicate with multiple clients at the same time, and it may communicate with each client multiple times. In order for the web service to track data for the client during asynchronous communication, it must have a way to remember which data belongs to which client and to keep track of where each client is in the process of operations. In WebLogic Workshop, you use conversations to uniquely identify a given communication between a client and your web service and to maintain state between operations.
Conversations are essential for any web service involved in asynchronous communication. This includes web services that communicate with clients using callbacks or polling interfaces, and web services that use controls with callbacks.
Best Practices for Designing Asynchronous Interfaces
This section discusses the best practices for creating and using web services and Java controls with asynchronous interfaces. The first topic describes how to use polling as an alternative to callbacks. Then, various design principles are recommended for designing web services and Java controls that can be called by both other web services and JSP (web) pages.
Designing Robust Asynchronous Interfaces
The preceding sections have presented various design options that can be included when building web services and Java controls. Given these options, what exactly constitutes a good design and creates a successful and robust web service or Java control? This topic explores several typical design solutions.
Do I Need an Asynchronous Interface?
The first question you might need to answer for a web service or Java control is whether the service or control needs to be asynchronous. There are certainly cases where a non-conversational, synchronous service or control will suffice, especially when the functionality it implements is relatively small, the request handling is relatively short, and the underlying infrastructure supporting this web service is solid, for instance if you are working on a fail-proof intranet or if your control is called by a (synchronous) web service on the same server. However, if any of these factors are not true or uncertain at the time of design, you will want to make your service or control asynchronous.
Do I Need to Use Callbacks?
Callbacks are a powerful approach to designing asynchronous web services or Java controls, relieving the client from periodically checking a request's status, as is required with polling. Especially when it is unclear how long a request will take to process, or if processing times vary wildly, using a callback is likely the most elegant implementation of asynchrony and loose coupling. Using callbacks in combination with buffering of both methods and callbacks is particularly effective in dealing with high-volume traffic. However, callbacks require that the client is designed to accept incoming messages and is hosted in an environment that supports message delivery.
Do I Need to Use Polling?
All asynchronous web services and Java controls should provide a polling interface. If the web service or Java control is asynchronous, a polling interface is required by any client that cannot accept callbacks; a polling interface is the only way such a client can obtain the results of operations initiated by asynchronous method invocations. You should think of a polling interface as the foundation interface of a web service or Java control, and callbacks as "extra" functionality that is convenient for clients who can handle callbacks.
The exception to this guideline is a Java control for which the only clients will be conversational web services or Java controls invoked by conversational web services. Conversational WebLogic Workshop web services can always accept callbacks. However, Java controls should be designed to be reusable. Assuming that the only clients a Java control will ever have are WebLogic Workshop web services limits the reusability of the Java control.
A Robust Web Service or Java Control
To create an asynchronous web service or Java control that is robust and handles all situations, it is recommended that you implement both a callback and a polling interface. Your design might (among others) include the following methods:
- A start_request_asynch buffered method that the client will call to initiate a request. The method starts a conversation and notes that the callback mechanism will be used when the results are ready.
- A callback_results buffered callback that sends the results to the client when the request is completed and finishes the conversation.
- A start_request_synch buffered method that the client will call to initiate a request. The method starts a conversation and notes that the polling mechanism will be used when the results are ready.
- A check_status unbuffered method that the client will periodically call to check the status of the request. The method continues a conversation and returns a Boolean value indicating whether or not the request has been completely handled.
- A get_results unbuffered method that the client will call to get the results of the request. The method finishes the conversation.
Comments
Post a Comment