public abstract class AbstractQuorum<S extends Remote,C extends QuorumClient<S>> extends Object implements Quorum<S,C>
| Modifier and Type | Class and Description | 
|---|---|
protected static class  | 
AbstractQuorum.E
Simple event impl. 
 | 
protected class  | 
AbstractQuorum.QuorumActorBase
Base class for  
QuorumActor implementations. | 
protected class  | 
AbstractQuorum.QuorumWatcherBase
Base class for  
QuorumWatcher implementations. | 
| Modifier and Type | Field and Description | 
|---|---|
protected static String | 
ERR_BAD_TOKEN
Text when an operation is not permitted because the new value for the
 lastValidToken is not strictly greater than the current value. 
 | 
protected static String | 
ERR_CAN_NOT_MEET
Text when an operation is not permitted because the quorum can not meet. 
 | 
protected static String | 
ERR_NOT_IN_CONSENSUS
Text when an operation is not permitted because the service has not cast
 its vote for a lastCommitTime around which there is a consensus of
 (k+1)/2 quorum members. 
 | 
protected static String | 
ERR_NOT_MEMBER
Text when an operation is not permitted because the service is not a
 quorum member. 
 | 
protected static String | 
ERR_NOT_PIPELINE
Text when an operation is not permitted because the service is not part
 of the write pipeline. 
 | 
protected static String | 
ERR_QUORUM_BREAK
Message when a quorum breaks.. 
 | 
protected static String | 
ERR_QUORUM_MET
Text when an operation is not permitted while the quorum is met. 
 | 
protected int | 
kmeet
The minimum #of joined services that constitutes a quorum as defined by
  
(k + 1) / 2 . | 
protected ReentrantLock | 
lock
The lock protecting state changes in the remaining fields and used to
 provide  
Conditions used to await various states. | 
protected static org.apache.log4j.Logger | 
log  | 
protected static org.apache.log4j.Logger | 
qlog
Dedicated logger for quorum state. 
 | 
| Modifier | Constructor and Description | 
|---|---|
protected  | 
AbstractQuorum(int k)
Constructor, which MUST be followed by  
#start() to begin
 operations. | 
| Modifier and Type | Method and Description | 
|---|---|
void | 
addListener(QuorumListener listener)
Add a listener 
 | 
void | 
assertLeader(long token)
Assert that the token is still valid and that the  
Quorum.getClient() is
 the quorum leader. | 
void | 
assertQuorum(long token)
Assert that the quorum associated with the token is still valid. 
 | 
void | 
awaitBreak()
Await a met break (blocking). 
 | 
void | 
awaitBreak(long timeout,
          TimeUnit units)
Await a met break (blocking). 
 | 
long | 
awaitQuorum()
Await a met quorum (blocking). 
 | 
long | 
awaitQuorum(long timeout,
           TimeUnit units)
Await a met quorum (blocking). 
 | 
protected void | 
finalize()  | 
QuorumActor<S,C> | 
getActor()
The object used to effect changes in distributed quorum state on the
 behalf of the  
QuorumMember. | 
Long | 
getCastVote(UUID serviceId)
Return the vote cast by the service. 
 | 
Long | 
getCastVoteIfConsensus(UUID serviceId)
Search for the vote for the service. 
 | 
C | 
getClient()
Return the  
QuorumClient iff the quorum is running. | 
protected C | 
getClientNoLock()  | 
UUID[] | 
getJoined()
Return the identifiers for the member services joined with this quorum. 
 | 
UUID | 
getLastInPipeline()
Return the  
UUID of the service which is the last service in the
 write pipeline. | 
protected long | 
getLastValidTokenFromQuorumState(C client)
Initialization method must return the lastValidToken from the durable
 quorum state and  
Quorum.NO_QUORUM if there is no durable state. | 
UUID | 
getLeaderId()
 | 
QuorumMember<S> | 
getMember()
Return the  
QuorumMember iff the quorum is running. | 
UUID[] | 
getMembers()
Return the identifiers for the member services (all known physical
 services for the logical service). 
 | 
UUID[] | 
getPipeline()
Return the service identifiers for the services in the write pipeline in
 the order in which they will accept and relay writes. 
 | 
UUID[] | 
getPipelinePriorAndNext(UUID serviceId)
Return the  
UUIDof the service in the pipeline which is
 immediately upstream from (prior to) and downstream from (next to) the
 specified service. | 
Map<Long,UUID[]> | 
getVotes()
Return an immutable snapshot of the votes cast by the quorum members. 
 | 
protected QuorumWatcher<S,C> | 
getWatcher()
The  
QuorumWatcher which informs this AbstactQuorum of
 changes occurring in the distributed state of the quorum. | 
protected void | 
guard(ThreadGuard.Guard r)
Execute a critical region which needs to be interrupted if we have to
 terminate the quorum. 
 | 
void | 
interruptAll()
Ensure that any guarded regions are interrupted. 
 | 
boolean | 
isHighlyAvailable()
Return  
true if Quorum.replicationFactor() is GT ONE (1). | 
boolean | 
isQuorum(int njoined)
Return  
true iff the argument is large enough to constitute a
 quorum. | 
boolean | 
isQuorumFullyMet(long token)
Return true iff the #of services joined with the quorum EQUALS
  
k AND the provided quorum token is valid. | 
boolean | 
isQuorumMet()
Return true iff the #of services joined with the quorum is GTE
  
(k + 1)/2. | 
long | 
lastValidToken()
The quorum token which was assigned the last time a leader was elected. 
 | 
protected void | 
launderThrowable(Throwable t)
Launder something thrown by the  
QuorumClient. | 
protected abstract AbstractQuorum.QuorumActorBase | 
newActor(String logicalServiceId,
        UUID serviceId)
 | 
protected abstract AbstractQuorum.QuorumWatcherBase | 
newWatcher(String logicalServiceId)
Factory method invoked by  
start(QuorumClient). | 
void | 
removeListener(QuorumListener listener)
Remove a listener (the quorum's client is always a listener). 
 | 
int | 
replicationFactor()
Return k, the target replication factor. 
 | 
protected void | 
sendEvent(QuorumEvent e)
Send the listener an informative event outside of the thread in which we
 actually process these events. 
 | 
void | 
start(C client)
Begin asynchronous processing. 
 | 
void | 
terminate()
Terminate any asynchronous processing associated with maintaining the
  
Quorum state. | 
long | 
token()
The current token for the quorum. 
 | 
String | 
toString()
Return a human readable representation of the local copy of the
 distributed quorum state (non-blocking). 
 | 
String | 
toStringAtomic()
Return a human readable representation of an atomic snapshot of the local
 copy of the distributed quorum state. 
 | 
protected static final transient org.apache.log4j.Logger log
protected static final transient org.apache.log4j.Logger qlog
protected static final transient String ERR_NOT_MEMBER
protected static final transient String ERR_NOT_PIPELINE
protected static final transient String ERR_NOT_IN_CONSENSUS
protected static final transient String ERR_BAD_TOKEN
protected static final transient String ERR_QUORUM_MET
protected static final transient String ERR_CAN_NOT_MEET
protected static final transient String ERR_QUORUM_BREAK
protected final int kmeet
(k + 1) / 2 .
 
 Note: This constant is isolated here so we can have "quorums" that
 require ALL services to be joined. For example, a highly available system
 that can replicate writes but can not resynchronize services that were
 not present during a quorum commit would specify the same value for
 k and kmeet in order to ensure that all services are
 joined before the quorum "meets".
 
 TODO Specify means to compute this. It is fixed by the constructor right
 now. Maybe we should just pull out an interface for this?
protected final ReentrantLock lock
Conditions used to await various states. This is exposed
 to concrete implementations of the AbstractQuorum.QuorumWatcherBase.protected AbstractQuorum(int k)
#start() to begin
 operations.protected void guard(ThreadGuard.Guard r) throws InterruptedException
r - The lambda.InterruptedExceptionprotected void finalize()
                 throws Throwable
public void start(C client)
QuorumListener, the QuorumActor
 and QuorumWatcher are created, and asynchronous discovery is
 initialized for the QuorumWatcher.protected long getLastValidTokenFromQuorumState(C client)
Quorum.NO_QUORUM if there is no durable state.public void interruptAll()
public void terminate()
QuorumQuorum state.protected abstract AbstractQuorum.QuorumActorBase newActor(String logicalServiceId, UUID serviceId)
logicalServiceId - The identifier of the logical service corresponding to the
            highly available quorum.serviceId - The UUID of the service on whose behalf the actor will
            act.QuorumActor which will effect changes in the
         distributed state of the quorum.protected abstract AbstractQuorum.QuorumWatcherBase newWatcher(String logicalServiceId)
start(QuorumClient).
 
 Note: Additional information can be passed to the watcher factor by
 derived classes. For example, the UUID of the logical service to
logicalServiceId - The identifier of the logical service whose quorum state
            will be watched.QuorumWatcher which will inform this
         AbstactQuorum of changes occurring in the distributed
         state of the quorum.public String toString()
public String toStringAtomic()
public C getClient()
QuorumQuorumClient iff the quorum is running.getClient in interface Quorum<S extends Remote,C extends QuorumClient<S>>QuorumClient.protected C getClientNoLock()
public QuorumMember<S> getMember()
QuorumQuorumMember iff the quorum is running.getMember in interface Quorum<S extends Remote,C extends QuorumClient<S>>QuorumMember.public QuorumActor<S,C> getActor()
QuorumMember.getActor in interface Quorum<S extends Remote,C extends QuorumClient<S>>QuorumActor which will effect changes in the
         distributed state of the quorum -or- null if the
         client is not a QuorumMember (only quorum members can
         take actions which effect the distributed quorum state).IllegalStateException - if the quorum is not running.protected QuorumWatcher<S,C> getWatcher()
QuorumWatcher which informs this AbstactQuorum of
 changes occurring in the distributed state of the quorum.IllegalStateException - if the quorum is not running.public final void addListener(QuorumListener listener)
QuorumaddListener in interface Quorum<S extends Remote,C extends QuorumClient<S>>listener - The listener.public final void removeListener(QuorumListener listener)
QuorumremoveListener in interface Quorum<S extends Remote,C extends QuorumClient<S>>listener - The listener.public final int replicationFactor()
Quorum
 A normal quorum requires a simple majority and a replication factor that
 is a non-negative odd integer (1, 3, 5, 7, etc). For this case, a quorum
 exists only when (k + 1)/2 physical services for the same
 logical service have an agreement on state. A single service with
 k := 1 is the degenerate case and has a minimum quorum size
 of ONE (1). High availability is only possible when k is GT
 ONE (1). Thus k := 3 is the minimum value for which services
 can be highly available and has a minimum quorum size of 2.
replicationFactor in interface Quorum<S extends Remote,C extends QuorumClient<S>>Quorum.isQuorum(int)public final boolean isQuorum(int njoined)
Quorumtrue iff the argument is large enough to constitute a
 quorum.
 Note: This method makes it easier to write code that obeys policies other than simple majority rule. For example, a quorum could exist only when ALL services are joined. This alternative rule is useful when the services do not support a resynchronization policy. For such services, all services must participate in all commits since services can not recover if they miss a commit. Simple replication is an example of this policy.
public final boolean isHighlyAvailable()
Quorumtrue if Quorum.replicationFactor() is GT ONE (1).
 High availability exists (in principle) when the
 Quorum.replicationFactor() k is greater than one. High
 availability exists (in practice) when the Quorum
 is met for a Quorum that is
 configured for high availability.isHighlyAvailable in interface Quorum<S extends Remote,C extends QuorumClient<S>>true if this Quorum is highly available
         in principlepublic final long lastValidToken()
QuorumlastValidToken in interface Quorum<S extends Remote,C extends QuorumClient<S>>public final UUID[] getMembers()
QuorumgetMembers in interface Quorum<S extends Remote,C extends QuorumClient<S>>UUIDs of the member services.public final Map<Long,UUID[]> getVotes()
Quorumpublic final Long getCastVote(UUID serviceId)
QuorumgetCastVote in interface Quorum<S extends Remote,C extends QuorumClient<S>>serviceId - The service.null if the
         service has not cast a vote.public Long getCastVoteIfConsensus(UUID serviceId)
QuorumgetCastVoteIfConsensus in interface Quorum<S extends Remote,C extends QuorumClient<S>>serviceId - The service identifier.null if the service is not participating in a
         consensus.public final UUID[] getJoined()
Quorumpublic final UUID[] getPipeline()
QuorumgetPipeline in interface Quorum<S extends Remote,C extends QuorumClient<S>>UUIDs of the ordered services in the write pipeline.public final UUID getLastInPipeline()
QuorumUUID of the service which is the last service in the
 write pipeline.getLastInPipeline in interface Quorum<S extends Remote,C extends QuorumClient<S>>UUID of the last service in the write pipeline or
         null if there are no services in the write pipeline.public final UUID[] getPipelinePriorAndNext(UUID serviceId)
QuorumUUIDof the service in the pipeline which is
 immediately upstream from (prior to) and downstream from (next to) the
 specified service. These are, respectively, the service from which it
 receives data (upstream) and to which it sends data (downstream).getPipelinePriorAndNext in interface Quorum<S extends Remote,C extends QuorumClient<S>>serviceId - The service id.null if the serviceId does not appear
         in the write pipeline -or- an array of two elements whose values
         are: [0] The upstream serviceId in the write pipeline, which will
         be null iff serviceId is the first service in
         the write pipeline; and [1] The downstream service in the write
         pipeline, which will be null iff serviceId is
         the last service in the write pipeline.public final UUID getLeaderId()
QuorumgetLeaderId in interface Quorum<S extends Remote,C extends QuorumClient<S>>UUID of the leader Quorum leader -or-
         null if the quorum is not met.public final long token()
QuorumQuorum.NO_QUORUM. When a leader is elected, it sets the current
 token as token := lastValidToken() + 1. The current token is
 cleared to Quorum.NO_QUORUM if the leader leaves the met quorum. It is
 cleared Quorum.NO_QUORUM if the quorum breaks. While a leader may be
 elected many times for the same lastCommitTime, a new quorum
 token is assigned each time a leader is elected.public final void assertQuorum(long token)
QuorumQuorum.token() somewhere.
 This method may then be invoked to verify that the saved token is still
 valid and, hence, that the quorum is still met.assertQuorum in interface Quorum<S extends Remote,C extends QuorumClient<S>>token - The token for the quorum.public final void assertLeader(long token)
QuorumQuorum.getClient() is
 the quorum leader.assertLeader in interface Quorum<S extends Remote,C extends QuorumClient<S>>token - A quorum token.public final boolean isQuorumMet()
Quorum(k + 1)/2. A service with a met quorum is highly available
 in practice.isQuorumMet in interface Quorum<S extends Remote,C extends QuorumClient<S>>public final boolean isQuorumFullyMet(long token)
Quorumk AND the provided quorum token is valid. A service with a
 fully met quorum may be eligible to release storage associated with
 historical allocations since it does not need to maintain history in
 support of resynchronization of disconnected quorum services.isQuorumFullyMet in interface Quorum<S extends Remote,C extends QuorumClient<S>>token - The quorum token.public final long awaitQuorum()
                       throws InterruptedException,
                              AsynchronousQuorumCloseException
Quorumis not met, then this
 will block until the Quorum meets.
 This watches the current token and will return as soon as the token is valid.
awaitQuorum in interface Quorum<S extends Remote,C extends QuorumClient<S>>AsynchronousQuorumCloseException - if Quorum.terminate() is invoked while awaiting a quorum
             meet.InterruptedExceptionpublic final long awaitQuorum(long timeout,
               TimeUnit units)
                       throws InterruptedException,
                              TimeoutException,
                              AsynchronousQuorumCloseException
QuorumQuorumis not met, then this
 will block until the Quorum meets.awaitQuorum in interface Quorum<S extends Remote,C extends QuorumClient<S>>timeout - The timeout.units - The timeout units.TimeoutException - if the timeout expired before the quorum met.AsynchronousQuorumCloseException - if Quorum.terminate() is invoked while awaiting a quorum
             meet.InterruptedExceptionpublic final void awaitBreak()
                      throws InterruptedException,
                             AsynchronousQuorumCloseException
QuorumawaitBreak in interface Quorum<S extends Remote,C extends QuorumClient<S>>AsynchronousQuorumCloseException - if Quorum.terminate() is invoked while awaiting a quorum
             break.InterruptedExceptionpublic final void awaitBreak(long timeout,
              TimeUnit units)
                      throws InterruptedException,
                             TimeoutException,
                             AsynchronousQuorumCloseException
QuorumawaitBreak in interface Quorum<S extends Remote,C extends QuorumClient<S>>timeout - The timeout.units - The timeout units.TimeoutException - if the timeout expired before the quorum breaks.AsynchronousQuorumCloseException - if Quorum.terminate() is invoked while awaiting a quorum
             break.InterruptedExceptionprotected void sendEvent(QuorumEvent e)
QuorumListener. The inner Runnable will block
 waiting for the lock before it sends the event, so clients will
 not see events propagated unless they have been handled by this class
 first.e - The event.protected void launderThrowable(Throwable t)
QuorumClient.t - The throwable.Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.