...
- It is not a goal to give the membership system a public API for use by geode users. The membership system will have an internal API and be usable in isolation, but we don't intend to advertise it as a publicly available component by itself.
- It is not a goal to create an SPI that allows different membership systems to be swapped in.
- It is not a goal to change the membership algorithms or wire protocol in any way.
Solution
Describe your solution and how it’s going to solve the problem. This is likely the largest section of your proposal and might even include some high-level diagrams if you are proposing code changes. While all important aspects need to be covered, also keep in mind that shorter documents are more likely to be read.
We will create a new gradle subproject called geode-membership. All of the code in the org.apache.geode.distributed.internal.membership.gms and related unit tests will be moved out of geode-core and into geode-membership. geode-core will have a dependency on geode-membership, and interact with membership through its API, defined below.
...
The membership code currently has a number of dependencies on other classes within geode core. We will break these dependencies in essentially three two different ways:
- Move the dependencies to a separate subproject - serialization is moving to separate subproject so that membership can depend directly on that
- Inject dependencies at runtime - dependencies such as gemfire stats can be injected into the membership system by providing interfaces such as GMSStatsListener MembershipStatistics (see below) that geode core must provide when creating the membership system.Wrap the membership APIs - some functionality is membership is tied to the rest of geode-core - for example DistributedMember is a public class that contains membership information as well as other, non membership related information. In geode-core, we can wrap the GMSMember in an appropriate class for use in the rest of geode-core.
Classes used to wrap the membership APIs or inject dependencies into membership will be put in the org.apache.geode.distributed.internal.membership.adapter package.TODO
geode-membership API
The geode-membership subproject will provide the following API to the rest of the system. We will enforce that other parts of the system can only interact with this API.
...
PlantUML |
---|
@startuml interface MembershipManagerFactoryMembershipFactory { + static newMembershipManagerFactorynewMembershipFactory() ---- + set...() } interface MembershipManagerMembership { Core class of a running membership system. + getMembershipView(): MembershipView } interface Messenger { + send(Message) } interface MembershipView { + getMembers(): List<MemberID> } interface MemberID { A single member of the system } interface MembershipListener { } interface MessageHandler { } interface Authenticator { } interface StatsListener { } interface Config { } interface MembershipView { } MembershipManagerFactoryMembershipFactory --> MembershipManagerMembership : creates MembershipManagerFactoryMembershipFactory *-- Authenticator MembershipManagerFactoryMembershipFactory *-- StatsListener MembershipManagerFactoryMembershipFactory *-- MessageHandler MembershipManagerFactoryMembershipFactory *-- Config MembershipManagerFactoryMembershipFactory *-- MembershipListener MembershipManagerMembership *-- Messenger MembershipManagerMembership *-- MembershipView MembershipView *-- MemberID @enduml |
...
Code Block | ||
---|---|---|
| ||
/** * Creates the membership system, given the provided configuration */ interface MembershipManagerFactoryMembershipFactory { static MembershipManagerFactoryMembershipFactory newMembershipManagerFactorynewMembershipFactory() setConfig(Config) setAuthenticator(Authenticator) setMembershipListener(MembershipListener) setMessageHandler(MessageHandler) setStatsListener(StatsListener) setMemberFactory(MemberIDFactory) create() : MembershipManagerMembership } /** * Core class of a running membership system. */ interface MembershipManagerMembership { getMembershipView(): MembershipView getMessenger(): Messenger getLocalMember(): MemberID contactedBy(MemberID) isShunned(MemberID) close() isClosed() } /** * API for sending messages to other members, using memberships messaging system * Membership currently allows geode-core to send messages over it's UDP messaging system. * This interface provides that functionality. */ interface Messenger { send(Message) /** Get an object the represents the messages that have been sent * through this messenger. This is used in waitForMessageState * To wait for these messages to arrive on the remote side */ getMessageState(): Object waitForMessageState(Object) } /** * Interface used to create a MemberID from a set of properties * This API is provided solely to allow geode-core to add additional * properties to the MemberID that are not relevant to membership * For example DurableClientAttributes. Membership will provide * A default MemberID which just has the membership relevant attributes interface MemberIDFactory { MemberID create(host, port, uuid, ...) } /** * A single member of the system. In practice, this will * be implemented by InternalDistributedMember */ interface MemberID { } /** * Provides the current members of the system */ interface MembershipView { List<MemberID> getMembers() } /** * Receives notifications about changes to membership */ interface GMSMembershipListenerMembershipListener { memberJoined(GMSMemberMemberID) memberDeparted(GMSMemberMemberID) forceDisconnected() } /** * Receives all messages sent from other members */ interface MessageHandler { processMessage(Message) } /** * Interface used by membership to authenticate other members */ interface Authenticator { } /** * Interface to notify statistics systems about membership changes */ interface StatsListener { memberJoined() memberDeparted() } /** * Primitive configuration options for membership * - timeouts, etc. */ interface Config { getJoinTimeout() ... } |
...
geode-serialization API (DRAFT)
...