Distributed Startup
Intent
Allow any number of mutually inter-dependant subsystems to initialise without causing deadlock or infinite recursion.
Motivation
Systems that consist of a number of comunicating processes always need to initialise in a controlled manner to ensure that each provider is available to each subscriber without causing deadlock or infinite recursion.
For example, the IO subsystem may be required by the error reporting subsystem to output errors, but if the IO subsystem fails to initialise, it needs to report an error.
Applicability
Use the distributed startup pattern when:
- You have a number of event producers and consumers
- The producers/consumers are to be (or may expect to be) distributed over a network
Structure
This pattern spans both the client and server sides of the network.

Participants
Abstract_Producer
- Provides services to the system

Abstract_Consumer
- Requires services of the system

Startup_Coordinator
- Synchronises the producers and consumers
Concrete_Producer
- Implements the Abstract_Producer interface.
Concrete_Consumer
- Implements the Abstract_Consumer interface.
Concrete_Producer_Consumer
- Implements the Abstract_Consumer and Concrete_Consumer interfaces.
Collaborations

Each Concrete_Producer announces that the first phase of its startup is complete to the Startup_Coordinator. If the Startup_Coordinator is not present/able to handle the message, the Concrete_Producer exits after informing the Startup_Coordinator of the failure.
Each Concrete_Consumer announces that the first phase of its startup is complete to the Startup_Coordinator. If the Startup_Coordinator is not present/able to handle the message, the Concrete_Consumer exits after informing the Startup_Coordinator of the failure.
An arbitrary time later, the Startup_Coordinator informs the consumers that all producers are ready for subscription. This happens when all producers and consumers have indicated their readiness.
An arbitrary time later, the Startup_Coordinator informs all the consumers that its OK to subscribe to the producers.
Each consumer subscribes to the services it needs.
When a consumer has subscribed to all the services it needs, it informs the Startup_Coordinator.
When every consumer has subscribed to the services it needs, the startup first tells all produces to begin processing, then tells all consumers to begin processing.
NOTE: Since both the producers and consumers must contact the Startup_Coordinator to initialise the entire system, both the producers and consumers must subscribe to the Startup_Coordinator. This is the weak point in the pattern, and a strategy of a number of retries before failure should be used.
Consequences
The distributed startup pattern has the following consequences:
- Decoupling of producers from consumers. There are no compile time dependencies between the two types of object.
- Improved extensiblity. Adding new producers and consumers does not affect existing ones.
Implementation
Every producer and consumer must still connect to the Startup_Coordinator, which must decide when it is safe to start the system. A number of algorithms may be employed to start the system in a degraded or stand-by state.
Failure of a consumer to connect to a producer should be reported to the startup co-ordinator. Hence, if a user-interface or logging producer has started successfully, this can be used to report the error.
Related Patterns
The abstract factory pattern can be combined to spawn one producer per consumer.
