Sometimes, the basic server pattern approach is not enough to model more complex situations. Occasionally, a request needs be suspended until the server reaches or leaves a special state. The guarded suspension pattern (Grand, 1999; Lea, 1997) handles the suspension of a service call which is synchronized to meet a precondition.
Consider the implementation of a regular queue. This queue can be the interchange point in a producer-consumer interaction. Such a queue is modelled using a server process which provides two different services: push and pull. The server state is an immutable data structure that implements a queue using a pair of lists (Okasaki, 1996). Using the server pattern, the implementation of the queue would look like:
To use this abstraction, the queue is created using the new function:
The serialization of the two services (push and pull), inherent to the definition of a generic server, ensures a correct concurrent access to the queue. However, there is a possibility for deadlock when a customer requests a service to pull an empty queue: the server is blocked in an infinite loop where Head and Tail are empty lists. No more requests are handled, even if there are processes trying to store values in the queue. The guard condition can be considered as a special case, but the definition of a basic server requires the computation of a response prior to attending further requests.
As a solution, the server pattern is extended to handle guarded suspensions. Now, a request may be temporarily suspended pending a precondition. Figure 2 shows a scenario with the expected producer-consumer behavior.
This pattern is to be applied if:
- server services must synchronize access to critical sections because process requests imply server state updates, and
- current server state makes it impossible for one of its services to run over, and the only way to leave such state is a call from another synchronized process
Fig. 2. Producer-consumer scenario (using a global queue)
An extension to the standard server pattern defines as part of the state all the suspended requests (Suspended) and, besides the Behavior function, takes two additional parameters:
- Guard: State x Req -> Boolean, which checks whether the server state is valid for the request and,
- Resume: State x [{Client, Req}] -> none | {ok, {Client, Req}, [{Client, Req}]}, which checks when a suspended process can be waken up.
The implementation of this new abstraction is:
With this abstraction, a queue with guarded suspension is implemented as:
- Grand,M.(1999). Patterns in Java: A catalog of reusable design patterns illustrated with UML, volume 1. NY, USA;London, UK; Sidney, Australia: John Wiley and Sons
- Lea, D. (1997). Concurrent programming in java: Design principles and patterns Reading, Mass.: Addison-Wesley
- Okasaki, C. (1996). Functional data structures The second international summer school on advanced funtional programming tecniques




