Variables aleatorias discretas y continuas
3.2. Ejemplos de distribuciones discretas
In synchronous communication (figure 2.2), one component waits until the other pro- vides an answer to its request and proceeds only after a response is provided. The requests are delivered immediately to the service provider, and the requesting compo- nent blocks until it receives a response.
When communicating asynchronously (figure 2.3), the component that issues the request proceeds without waiting for an answer. The requests aren’t delivered to the service provider but stored in an intermediate buffer and from there will be delivered to their intended recipient.
Looking at how different these two alternatives are, the decision to use synchronous or asynchronous communication should be based on their strengths and weaknesses. Let’s examine the upsides and downsides of each approach a bit further.
Of the two, synchronous communication is more straightforward: the recipient of the call is known in advance, and the message is received immediately (see figure 2.4). The invocation, processing, and response occur in the same thread of execution (like a Java thread if the call is local or a logical thread if it’s remote). This allows you to prop- agate a wealth of contextual information, the most common being the transactional and security context. Generally, the infrastructure required to set it up is simpler: a method call or a remote procedure call. Its main weaknesses are that it’s not scalable and it’s less resilient to failure.
Scaling up is a problem for synchronous communication because if the number of simultaneous requests increases, the target com-
ponent has few alternatives, for example:
Trying to accommodate all requests as they arrive, which will crash the system
Throttling some of the requests to bring the load to a bearable level2
2 Throttling is the process of limiting the number of requests that a system can accommodate by either post- poning some of them or dropping them altogether.
Requester
Provider
2 3
1 4
Figure 2.2 Synchronous invocation: the requester suspends execution until it receives an answer. Requester Provider 1 2 3 4
Figure 2.3 Asynchronous invocation: the requester doesn’t block and executes in parallel with the provider.
Invoker Provider
request response
Figure 2.4 Synchronous message exchange: the message is received immediately by the provider.
34 CHAPTER 2 Enterprise integration fundamentals
When the load increases, the application will eventually fail, and you can do little about it.
The lack of resilience to failure comes from the fundamental assumption that the service provider is working properly all the time. There’s no contingency, so if the ser- vice provider is temporarily disabled, the client features that depend on it won’t work either. The most obvious situation is a remote call that fails when the service provider is stopped, but this also applies to local calls when an invoked service throws a Run- timeException.
DEALING WITH EXCEPTIONS Exception-handling strategies are beyond the scope of this discussion, but it should be noted that a service can attempt to retry a synchronous call if the downtime of the service provider is very short, but it’s generally unacceptable to block for a long time while wait- ing for a service to come up.
Asynchronous communication offers better opportunities to organize the work on the service provider’s side. Requests aren’t processed immediately but left in an intermedi- ate storage and from there are delivered to the service provider whenever it can handle them (see figure 2.5). This means the requests will never be lost, even if the service pro- vider is temporarily down, and also that a pool of concurrent processes or threads can be used to handle multiple requests in parallel.
Asynchronous message exchange provides control for the behavior of the system under heavy load: a larger number of concurrent consumers means a better through- put. The caveat is that it puts the system under more stress. The point is that, unlike synchronous calls where the load of the system is controlled by the requesting side, in the asynchronous model, the load of the sys-
tem is controlled by the service provider’s side. Furthermore, asynchronous communica- tion has better opportunities for retrying a failed request, which improves the overall resilience to failure of the system.
You saw that asynchronous communication has obvious advantages in terms of scalability and robustness, but there’s a price to be paid for that: complexity. The messaging middleware that performs the message storage and for- warding function is an additional mechanism that must be integrated with the application, which means that instead of a simple method call, you must deal with supplemental APIs and protocols. Not only does the code become more complex, but also a performance over- head is introduced. Invoker Provider Message Message Message Message Message Message Store
send message receive message
Figure 2.5 Asynchronous message exchange: the message is stored in an intermediate buffer before being received by the provider.
35
Synchronous and asynchronous communication
Also, in a request-reply scenario using the synchronous approach, the result of an operation can be easily retrieved: when the execution of the caller resumes, it already has the result. In the case of asynchronous communication, the retrieval of the result is a more complex matter. It can either follow the Future Object pattern (as in java.util.concurrent.Future), where after the asynchronous invocation, the invoker is provided with a handle to the asynchronous job and can poll it to find out whether a result is available, or the requester might provide a callback to be executed in case the request has been processed.
After issuing an asynchronous request, you have two components that execute independently: the requester that continues doing its work and the service provider whose work is deferred until later. Concurrency is a powerful tool for increasing the application performance, but it adds complexity to your application too. You have to consider concerns like thread--safety, proper resource management, deadlock, and starvation avoidance. Also, at runtime, it’s harder to trace or debug a concurrent application. Finally, the two concurrent operations will typically end up executing in distinct transactions. Synchronous and asynchronous communication are compared in more detail in table 2.1.
The advantages and disadvantages of the two paradigms should be carefully consid- ered when choosing one over the other. Traditionally, the integration between enter- prise applications is based on message-driven, asynchronous mechanisms.
As the capabilities of hardware systems increase, especially when it comes to execu- tion of concurrent processes and as multicore architectures become more pervasive, you’ll find opportunities to apply the patterns that are specific to integrating multiple applications to different components of an individual application. The modules of the application may interact, not through a set of interfaces that need to be kept up to date, but through messages. Various functions might be executed asynchronously, freeing up their calling threads to service other requests. Distinct message handlers,
Table 2.1 Synchronous and asynchronous communication compared
Synchronous Asynchronous
Definition Request is delivered immediately to provider, and the invoker blocks until it receives a response.
The invoker doesn’t wait to receive a response. Requests are buffered and will be processed when the provider is ready.
Advantages – Simple interaction model – Immediate response
– Allows the propagation of invocation context (transaction, security)
– Good scalability under load – Resilience to failure (requester and
provider needn’t be available at the same time)
Disadvantages – Lack of resilience to failure – Doesn’t scale properly under load
– Complex interaction model due to increased concurrency
36 CHAPTER 2 Enterprise integration fundamentals
otherwise perfectly encapsulated components, may be grouped together in an atomic operation.