Conversations occur by multiple conversation partners exchanging messages. Identification of the conversation participants is a necessary precondition to any conversation and occurs at two levels:
- Each participant plays one or more roles designated by the conversation. For example, one participant may act as Requestor of a service while the other participant acts as Provider of a service. The conversation defines which participant can send what messages in which order to which other participant(s).
- The participant roles have to be mapped to participant instances: in order to start a conversation, a conversation initiator must send a message to a specific instance of another participant, usually identified by an address. This address can point to a single instance or to a set of instances which for example may be load balanced.
To get a conversation started, the conversation initiator must identify the instance of the conversation partner that it will send a message to. Typically, the participant addresses should not be hard-coded, but the initiator should identify the best participant to talk to. We call this process Discovery. Designing Discovery revolves around the following considerations:
- Addressability: Conversation participants direct messages to other participants via an address. this can be a resource locator (URI), a Message Channel name, or a similar unique identifier. These identifiers have to be embeddable in messages so that one participant can pass an address to another participant, e.g. through Referral.
- Centralized vs. Distributed: Some discovery processes rely on a central participant, such as a registry, to find conversation partners while others are fully decentralized and do not require such a "special" participant. Each approach has advantages and disadvantages. A central registry has knowledge about all services and can make smart decisions about how to fulfill a discovery request, for example based on load, proximity, or similar policies. However, a central registry can become a bottleneck or point of failure. Also, the registry can get out of sync with the reality when a registered service is no longer available. Lastly, a service has to "discover"" the registry in the first place, often via a well-known (i.e. hard-coded) address. Decentralized systems do not require such a central participant but can carry more overhead and can make it difficult to find the "best" conversation partner.
- Static v.s Dynamic Role Assignment: Many conversations inherently define the roles. For example, in a simple Asynchronous Request-Response conversation, the Requestor always discovers the Provider and initiates the conversation by sending a message to it. Some conversations, however, may require participants to negotiate roles: for example, multiple participants may dynamically elect a leader out of a pool of candidates using Leader Election.
- Precision: Discovery requires the initiator to express what type of conversation partner it is looking for. The initiator may specify its need using a role, a unique identifier, a set of criteria, or based on a refined ontology.
- Who decides: Some approaches require the initiator to determine with conversation partner is "best" after soliciting responses from all possible partners while dealing with missing or delayed responses. Other approaches may put more burden on the to-be-discovered services, requiring them to announce their presence, their functional and non-functional attributes, etc., but simplifying the task of the initiator.
- Dynamicity: Some environments are more static than others. For example, enterprise services may be reliable and do not come and go at will, even though individual instances may fail. However, on a short-range wireless network services may appear and disappear all the time. Relatively static environments can make Discovery more efficient, e.g. through caching.
- Trust: Allowing conversation partners to discover one another requires some amount of trust. How can a participant trust their conversation partner? Or can they trust the discovery process to deliver legitimate conversation partners? Reversely, Who should be allowed to "see" a service and connect to it?
Based on these considerations we discuss the following Discovery patterns:
- Dynamic Discovery allows participants ready to initiate a conversation to locate potential conversation partners without a central registry.
- Advertise Availability has participants ready to be engaged in a conversation announce their existence.
- Consult Directory locates conversation partners registered with a special participant acting as registry.
- Referral describes one service introducing new participants to an existing conversation partner.
- Leader Election describes multiple, known participants agree on their roles.
In typical systems, a combination of these Discovery patterns is common, driven by different numbers of participants to be discovered and different rates of Discovery. For example, directories may Advertise Availability to announce their presence so that they can subsequently support Consult Directory. This works well because the number of directories is small compared to the number of Discovery requests. Alternatively, participants may use Dynamic Discovery to discover directories and then engage in Consult Directory. Once a participant has discovered an initial conversation partner through Consult Directory he may be receive a Referral to related services.
Using see Intermediaries pushes the need for Discovery to the intermediary so that conversation initiators do not have to deal with it. The identity of the intermediary may be hard-coded so that no discovery is needed to start a conversation with the intermediary.
Reference: Pattern Language for Service Discovery in [PLoPD5].
Reference: [POSA3]