/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.apache.geode.distributed.internal.membership; import java.io.NotSerializableException; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReadWriteLock; import org.apache.geode.SystemFailure; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.internal.DMStats; import org.apache.geode.distributed.internal.DistributionMessage; import org.apache.geode.internal.logging.InternalLogWriter; /** * A MembershipManager is responsible for reporting a MemberView, as well as having explicit * protocol for leaving or joining the distributed system. * <p> * * Note that it is imperative to send a new manager a postConnect message after instantiation. * * */ public interface MembershipManager { /** * this must be sent to the manager after instantiation to allow it to perform post-connection * chores */ public void postConnect(); /** * Fetch the current view of memberships in th distributed system, as an ordered list. * * @return list of members */ public NetView getView(); /** * Returns an object that is used to sync access to the view. While this lock is held the view * can't change. * * @since GemFire 5.7 */ public ReadWriteLock getViewLock(); /** * Return a {@link InternalDistributedMember} representing the current system * * @return an address corresponding to the current system */ public InternalDistributedMember getLocalMember(); /** * Sanity checking, esp. for elder processing. Does the existing member (still) exist in our view? * * @param m the member * @return true if it still exists */ public boolean memberExists(DistributedMember m); /** * Is this manager still connected? If it has not been initialized, this method will return true; * otherwise it indicates whether the connection is stil valid * * @return true if the manager is still connected. */ public boolean isConnected(); /** * A test hook for healthiness tests */ public boolean isBeingSick(); /** * Instruct this manager to release resources */ public void shutdown(); /** * Forcibly shut down the manager and inform its listeners of the failure */ public void uncleanShutdown(String reason, Exception e); /** * A shutdown message has been received from another member */ public void shutdownMessageReceived(InternalDistributedMember id, String reason); /** * Stall the current thread until we are ready to accept view events * * @throws InterruptedException if the thread is interrupted while waiting * @see #startEventProcessing() */ public void waitForEventProcessing() throws InterruptedException; /** * Commence delivering events to my listener. * * @see #waitForEventProcessing() */ public void startEventProcessing(); /** * @param destinations list of members to send the message to. A list of length 1 with * <em>null</em> as a single element broadcasts to all members of the system. * @param content the message to send * @param stats the statistics object to update * @return list of members who did not receive the message. If * {@link DistributionMessage#ALL_RECIPIENTS} is given as thelist of recipients, this * return list is null (empty). Otherwise, this list is all of those recipients that did * not receive the message because they departed the distributed system. * @throws NotSerializableException If content cannot be serialized */ public Set send(InternalDistributedMember[] destinations, DistributionMessage content, DMStats stats) throws NotSerializableException; /** * Indicates to the membership manager that the system is shutting down. Typically speaking, this * means that new connection attempts are to be ignored and disconnect failures are to be (more) * tolerated. * */ public void setShutdown(); /** * Determine whether GCS shutdown has commenced * * @return true if it is shutting down */ public boolean shutdownInProgress(); /** * Returns a serializable map of communications state for use in state stabilization. * * @param member the member whose message state is to be captured * @param includeMulticast whether the state of the mcast messaging should be included * @return the current state of the communication channels between this process and the given * distributed member * @since GemFire 5.1 */ public Map getMessageState(DistributedMember member, boolean includeMulticast); /** * Waits for the given communications to reach the associated state * * @param member The member whose messaging state we're waiting for * @param state The message states to wait for. This should come from getMessageStates * @throws InterruptedException Thrown if the thread is interrupted * @since GemFire 5.1 */ public void waitForMessageState(DistributedMember member, Map state) throws InterruptedException; /** * Wait for the given member to not be in the membership view and for all direct-channel receivers * for this member to be closed. * * @param mbr the member * @return for testing purposes this returns true if the serial queue for the member was flushed * @throws InterruptedException if interrupted by another thread * @throws TimeoutException if we wait too long for the member to go away */ public boolean waitForDeparture(DistributedMember mbr) throws TimeoutException, InterruptedException; /** * Returns true if remoteId is an existing member, otherwise waits till timeout. Returns false if * remoteId is not confirmed to be a member. * * @param remoteId * @return true if membership is confirmed, else timeout and false */ public boolean waitForNewMember(InternalDistributedMember remoteId); /** * Release critical resources, avoiding any possibility of deadlock * * @see SystemFailure#emergencyClose() */ public void emergencyClose(); /** * Request the current membership coordinator to remove the given member */ public boolean requestMemberRemoval(DistributedMember member, String reason); /** * like memberExists() this checks to see if the given ID is in the current membership view. If it * is in the view though we try to connect to its failure-detection port to see if it's still * around. If we can't then suspect processing is initiated on the member with the given reason * string. * * @param mbr the member to verify * @param reason why the check is being done (must not be blank/null) * @return true if the member checks out */ public boolean verifyMember(DistributedMember mbr, String reason); /** * Initiate SUSPECT processing for the given members. This may be done if the members have not * been responsive. If they fail SUSPECT processing, they will be removed from membership. */ public void suspectMembers(Set members, String reason); /** * Initiate SUSPECT processing for the given member. This may be done if the member has not been * responsive. If it fails SUSPECT processing, it will be removed from membership. */ public void suspectMember(DistributedMember member, String reason); /** * if the manager initiated shutdown, this will return the cause of abnormal termination of * membership management in this member * * @return the exception causing shutdown */ public Throwable getShutdownCause(); /** * register a test hook for membership events * * @see MembershipTestHook */ public void registerTestHook(MembershipTestHook mth); /** * remove a test hook previously registered with the manager */ public void unregisterTestHook(MembershipTestHook mth); /** * If this member is shunned, ensure that a warning is generated at least once. * * @param mbr the member that may be shunned */ public void warnShun(DistributedMember mbr); public boolean addSurpriseMember(DistributedMember mbr); /** * if a StartupMessage is going to reject a new member, this should be used to make sure we don't * keep that member on as a "surprise member" * * @param mbr the failed member * @param failureMessage the reason for the failure (e.g., license limitation) */ public void startupMessageFailed(DistributedMember mbr, String failureMessage); /** * @return true if multicast is disabled, or if multicast is enabled and seems to be working */ public boolean testMulticast(); /** * Returns true if the member is a surprise member. * * @param m the member in question * @return true if the member is a surprise member */ public boolean isSurpriseMember(DistributedMember m); /** * Returns true if the member is being shunned */ public boolean isShunned(DistributedMember m); /** * Forces use of UDP for communications in the current thread. UDP is connectionless, so no tcp/ip * connections will be created or used for messaging until this setting is released with * releaseUDPMessagingForCurrentThread. */ public void forceUDPMessagingForCurrentThread(); /** * Releases use of UDP for all communications in the current thread, as established by * forceUDPMessagingForCurrentThread. */ public void releaseUDPMessagingForCurrentThread(); /** * After a forced-disconnect this method should be used once before attempting to use * quorumCheckForAutoReconnect(). * * @return the quorum checker to be used in reconnecting the system */ public QuorumChecker getQuorumChecker(); /** * Frees resources used for quorum checks during auto-reconnect polling. Invoke this method when * you're all done using the quorum checker. * * @param checker the QuorumChecker instance */ public void releaseQuorumChecker(QuorumChecker checker); }