1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 */ 6 7 package com.sleepycat.je.rep.arbitration; 8 9 import java.util.logging.Logger; 10 11 import com.sleepycat.je.Durability.ReplicaAckPolicy; 12 import com.sleepycat.je.rep.QuorumPolicy; 13 import com.sleepycat.je.rep.ReplicationMutableConfig; 14 import com.sleepycat.je.rep.impl.RepImpl; 15 import com.sleepycat.je.utilint.LoggerUtils; 16 17 /** 18 * The locus for management of this node's active arbitration state, and of the 19 * mechanisms available to this node for doing arbitration. 20 * <p> 21 * A node is in active arbitration state if 22 * <ul> 23 * <li> is the master 24 * <li> is lacking the required durability quorum 25 * <li> is maintaining its authoritative master status and its ability to 26 * commit writes through the good graces of an ArbiterProvider. 27 * </ul> 28 * <p> 29 * The Arbiter detects which arbitration options are available in the JE HA 30 * group. 31 */ 32 public class Arbiter { 33 34 /** 35 * True if this node is in active arbitration. 36 */ 37 private volatile boolean active; 38 39 private final ArbiterProvider provider; 40 41 private final RepImpl repImpl; 42 private final Logger logger; 43 44 /** 45 * Examine environment configuration and rep group membership to figure out 46 * which arbitration options are in operation for this HA group. 47 */ Arbiter(RepImpl repImpl)48 public Arbiter(RepImpl repImpl) { 49 this.repImpl = repImpl; 50 provider = new DesignatedPrimaryProvider(repImpl); 51 logger = LoggerUtils.getLogger(this.getClass()); 52 } 53 54 /** 55 * The replication node knows that it has lost its durability quorum, and 56 * wants to try to enter active arbitration mode. 57 * @return true if the node successfully transitions to active arbitration, 58 * or was already in active arbitration. 59 */ activateArbitration()60 public synchronized boolean activateArbitration() { 61 if (provider.attemptActivation()) { 62 active = true; 63 } else { 64 active = false; 65 } 66 return active; 67 } 68 69 /** 70 * The node has determined that it need not be in active arbitration. 71 * End the active arbitration state. If the node was not in active 72 * arbitration, do nothing. 73 */ endArbitration()74 public void endArbitration() { 75 synchronized(this) { 76 if (!active) { 77 return; 78 } 79 80 provider.endArbitration(); 81 active = false; 82 } 83 84 LoggerUtils.info(logger, repImpl, "Arbitration is inactivated"); 85 } 86 87 /** 88 * Return true if it's possible that this node can switch into active 89 * arbitration. The criteria for activation depend on the type of 90 * arbitration enabled for this node. 91 * <p> 92 * For example, if designated primary arbitration is used, then it's only 93 * possible to move into active arbitration if the Designated Primary 94 * configuration parameter is set for this node. If LWT Node arbitration is 95 * used, then this node must have a valid connection to the arbiter node. 96 */ activationPossible()97 public boolean activationPossible() { 98 return provider.activationPossible(); 99 } 100 101 /** 102 * Return true if this node is in active arbitration, and if arbitration 103 * should take precedence over the election quorum policy. 104 */ isApplicable(QuorumPolicy quorumPolicy)105 public boolean isApplicable(QuorumPolicy quorumPolicy) { 106 return active && (quorumPolicy.equals(QuorumPolicy.SIMPLE_MAJORITY)); 107 } 108 109 /** 110 * Return true if this node is in active arbitration, and if arbitration 111 * should take precedence over the durability quorum policy. 112 */ isApplicable(ReplicaAckPolicy ackPolicy)113 public boolean isApplicable(ReplicaAckPolicy ackPolicy) { 114 return active && (ackPolicy.equals(ReplicaAckPolicy.SIMPLE_MAJORITY)); 115 } 116 117 /** 118 * Return the arbitration-influenced election quorum size. Arbitration 119 * may reduce the value that would usually be indicated by the quorum 120 * policy. 121 */ getElectionQuorumSize(QuorumPolicy quorumPolicy)122 public int getElectionQuorumSize(QuorumPolicy quorumPolicy) { 123 return provider.getElectionQuorumSize(quorumPolicy); 124 } 125 126 /** 127 * Return the arbitration-influenced durability quorum size. Arbitration 128 * may reduce the value that would usually be indicated by the ack policy. 129 */ getAckCount(ReplicaAckPolicy ackPolicy)130 public int getAckCount(ReplicaAckPolicy ackPolicy) { 131 return provider.getAckCount(ackPolicy); 132 } 133 134 /** 135 * The replication configuration was changed. Check the new configuration 136 * to see it impacts active arbitration state or makes more arbitration 137 * mechanisms available. For example, if we are in active arbitration using 138 * designated primary arbitration, a change to the node's designated 139 * primary configuration parameter may affect whether this node can stay in 140 * active arbitration. 141 */ 142 public synchronized void processConfigChange(ReplicationMutableConfig newConfig)143 processConfigChange (ReplicationMutableConfig newConfig) { 144 145 if (!active) { 146 return; 147 } 148 149 if (provider.shouldEndArbitration(newConfig)) { 150 endArbitration(); 151 } 152 } 153 154 /** 155 * Return true if this node is in active arbitration. 156 */ isActive()157 public synchronized boolean isActive() { 158 return active; 159 } 160 } 161 162 163 164