I once read "All men make mistakes, but only wise men learn from their mistakes". This makes so much sense when designing applications. I mean you don't have to pay a price before you learn the right way of doing things. This is why we develop Best Practices (Do's and Don'ts).
One such Don't in the world of application design is a sync-over-async pattern. A sync-over-async switch occurs when a component synchronously invokes another component with an asynchronous implementation. Since the target component has an asynchronous implementation, but the invocation style is synchronous, what the runtime will do is intercept this call and switch it to an asynchronous one. This switch can cause a lot of unexpected behaviors and can cause thread pool depletion when processing a high volume.
My WebSphere Support Technical Exchange (WSTE) in December on WebSphere Process Server - Service Component Architecture Common Problems and Solutions, covers the disadvantages of a synch-over-asynch pattern in detail. You can find them in this techdoc here.
So, how do you ensure you are not using a sync-over-async pattern. Its simple, what I do is take a look at the module in WebSphere Integration Developer (WID).
1. Are there any components that have an asynchronous implementation, for example:
- Java™ Component (POJO) that implements the ServiceAsyncImpl interface
- Long running business process
- Human tasks
- JMS import
- MQ import
2. Ensure other components are not invoking it in a synchronous manner. To find the invocation style read the developerWorks article here.
I have used a shortcut to spot a sync-over-async switch, you might also find it useful. There are certain components that will always perform a synchronous invocation, given certain conditions. You should avoid such components to be paired with components with asychronous implementation. Because such a combination of components will invariably lead to a sync-over-asycn switch. For example, a web service export will always perform synchronous invocation, so if you have have a web service export invoke a long running bpel, you end up with sync-over-asycn switch. Another example would be a microflow invoking a MQ import for a request response operation. For a request response operation, microflow will always perform a synchronous invocation. And as a MQ import has an asynchronous implementation, you will end up with a sync-over-async switch.
To sum it up, please keep an eye for the scenarios below and avoid them.
- microflow->long running bpel (request response operation)
- microflow->message binding imports like MQ import (request response operation)
- WS export->long running bpel
- WS export->message binding imports like MQ import
In WebSphere Process Server V7 it gets better because you will see the following warning message displayed in the SystemOut.log when you are using a sync-over-async switch:
000000ac Core W CWSCA2011W: Service Component Architecture (SCA) is switching a synchronous call to an asynchronous call. Request will be sent in a new local transaction. Default timeout is 115000 milliseconds.