|
Realtime software sometimes involves collecting a sequence of messages. Further
action can be initiated only after complete sequence of messages has been
received. Collector state pattern handles such scenarios.
Intent
The main intention here is to manage sequence of events of same type. For
example, a Call object needs to collect all the digits to perform call routing. This will involve
activities like a timer start before each digit, digit collection, timer stop at
each digit collection, timeout on complete digit collection and call
routing on complete digit collection.
Also Known As
- Digit Collection Design Pattern
- Message Assembly Design Pattern
Motivation
The main objective of this design pattern is to efficiently handle scenarios
where message collection is involved. This involves counting the received
messages and recognizing the point where collection has been completed.
Applicability
The Collector State pattern can be used wherever there is a need to collect a
sequence of messages. It may also be used in handling of
periodic events like sanity punching.
Structure
This pattern consists of the following event handlers:
- Collected Message Handler: This
handler receives the messages being collected and takes a decision when
collection has been completed. When collection is in progress, this handler
activates a timer to keep track of progress of message collection.
- Timeout Handler: When a timeout takes
place, a decision needs to be taken about the status of message collection.
In some scenarios, timeout signals failure of message collection. In other
scenarios, timeout might signal a successful message collection.
Participants
The key participants in this pattern are the task sending the sequence of
small messages and the task collecting the message sequence to assemble a bigger
message or meaningful data.
Collaboration
The state machine implementing the collector state patterns collaborates with
the source of messages being collected and in some scenarios might report
completion of collection to the originator.
Consequences
Collector state pattern can result in triggering a state transition
corresponding to successful collection of messages. If a timeout takes place
before the collection has been completed, a state transition to an error
handling state might be initiated.
Implementation
As mentioned earlier, the components constituting Collector State pattern are
Collected Message handler and Timeout handler. The Collector
State pattern performs a timer start for each new small message collection,
timer stop at each small message collection and state exit on timeout to Call
Routing state or Partial Dialing state.
Here is an example of implementation of digit collection using this
pattern.
- Start timer of inter-digit timeout size.
- Call digit collection method on receipt of digit message.
- Restart timer for next digit.
- The digit collection can end in any of the following ways.
- On timeout, call 'call routing' function and perform state exit.
- On receipt of "end of digits" condition in digit message,
transition to "call routing" state.
- On receipt of given number of digit messages, transition to "call
routing" state.
Sample Code and Usage
Here is the sample code for a basic implementation of digit collection using the Collector State pattern.
| Digit
Collection Using the Collector State Pattern |
class CDigitCollectorState : public CState
{
int m_nReceivedDigits; // Count of received digits
const int m_nExpectedDigits; // Total number of expected digits
const int m_nMinimumNumberOfDigits; // Minimum number of expected digits
public:
// Handle the received Digit message
void OnDigit(CStateMachine& m, const DigitMsg* pMsg)
{
// Save the digit and increment the received digit counter
m.m_digits[m_nReceivedDigit++] = pMsg->GetDigit();
// Now check if the message explicitly signals the last digit, or if
// expected number of digits have been received.
if (pMsg->IsLastDigit() || (m_nReceivedDigits == m_nExpectedDigits))
{
// Digit collection has been completed, so proceed to call routing
m.ChangeState(pCallRoutingState);
}
else
{
// More digits are expected, so restart the digit timer
RestartDigitTimer();
}
}
// Handle Digit Timeout
virtual void OnDigitTimeout(CStateMachine& m)
{
if (m_nReceivedDigits < m_nMinimumNumberOfDigits)
{
// If too few digits have been received, the call moves
// to the state handling partial dialing
m.ChangeState(pPartialDialingState);
}
else
{
// If more than minimum digits are received and timeout
// takes place, assume that digit collection has been
// completed, so proceed with call routing.
m.ChangeState(pCallRoutingState);
}
}
};
|
Known Uses
This design pattern has been used in the following cases:
- Digit collection
- Collecting periodic sanity punch from a hardware unit.
- Collecting message segments to form a complete message. This
technique is used in several segmentation and reassembly protocols.
Related Patterns
Feature Design Patterns like
parallel and serial coordination are examples of other more general mechanisms
of handling a sequence of messages. |