Nunca he trabajado con la comunidad de Java.
— Miguel de Icaza (n. 1972). Desarrollador mexicano de software libre.
Nota: originalmente este texto lo escribí para poder mostrárselo a uno de los compañeritos del team por aquello de mensajes asíncronos con confirmación.
On Chapter 8.4.3 (Refactoring Synchronous to Asynchronous Interactions) of the book the author states that for synchronous to asynchronous service refactoring it is required to use a request-response communication. What is really defined is a request-null-response-null model combined with a caller/endpoint inversion of roles:
|(Figure 8.9a – The Asynchronous Communication detailed on the blueprints)|
However, there is a better approach for the web service asynchronous communication model:
- Instead of changing the synchronous request/reply interaction into a void, it is possible to introduce an "acknowledge message" response model: the architecture follows the original asynchronous communication concept but defines a request-acknowledge-response-acknowledge process flow, which has increased scalability an robustness, fulfilling most communication-failover needs (Figure 8.9b – The Enhanced Asynchronous Communication):
|(Figure 8.9b – The Enhanced Asynchronous Communication).|
- If any of the receivers is down (Endpoint on original request; caller on final response) it is defined a retry mechanism: If the caller does not receive an acknowledge for a finite amount of time (acknowledge timeout), it can try to dispatch the same message for a predefined number of times over a finite period interval between each one (retry number, retry interval).
- For the retry mechanism, the sender (Caller on original request; endpoint on final response) should send the message to a JMS queue for later delivery; this queue must have a Timer component that resends each message according to individual "failed-to-deliver" timestamps. It is mentioned in the book that this is an optional task; however all dispatching should go through a JMS queue as it limits the consumed resources and provides message delivery reliability.
- The retry mechanism can also dispatch all queued messages in one pass, if there is a ping service enabled on this architecture.
- For even more scalability, it is possible to add another indirection layer between the dispatching and business logic modules. This means the receiver component on the endpoint will not call directly a business component for message processing (i.e.: a Session EJB) but will send the message (even on raw, SOAP format) to another JMS queue. On the business layer resides a Message-Driven Bean whose function is to recover this messages and call the appropriate EJB (this assuming that for each message the application should follow different workflows). Although it is displayed on the original diagram, it is not explained in much detail.
As a good programming practice, if the document-style web service strategy is selected, all elements sent through the communications channel must be convertible between java objects and their xml representation by means of JAXB implementation frameworks (XMLBeans is a good option); using
Object Object.parse(String xmlString)
is time-consuming, error-prone and difficult to debug.
- Another area of concern is the web service security that must be integrated as part of all layers in the architecture; however this topic will be explained in a future article.
Footnotes and annotations
1. The ping service should be a synchronous web service that requests simple information between the caller and endpoint tiers; this component allows for tuning and resource optimization:
- In the event of communications disruption detection, all generated messages can be queued for later delivery without going through the retry mechanism (remember: any delivery failure generates an IOException with its accompanying stack trace).
- If the communication channel goes live again and is detected by the ping service, all queued messages could be redelivered on demand (according to creation timestamp) or en-masse.
2. The document-style web service strategy implies that the return values and parameters passed through both dispatcher/receiver methods implement the XML DOM specification; on the contrary, an rpc-style web service relies on passing/returning serializable java objects.