All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.distributed.internal.membership.jgroup.QuorumCheckerImpl Maven / Gradle / Ivy

There is a newer version: 2.0-BETA
Show newest version
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */

package com.gemstone.gemfire.distributed.internal.membership.jgroup;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.distributed.internal.membership.QuorumChecker;
import com.gemstone.gemfire.internal.LogWriterImpl;
import com.gemstone.gemfire.internal.ManagerLogWriter;
import com.gemstone.gemfire.internal.concurrent.ConcurrentHashSet;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import com.gemstone.org.jgroups.View;
import com.gemstone.org.jgroups.protocols.pbcast.GMS;
import com.gemstone.org.jgroups.stack.IpAddress;
import com.gemstone.org.jgroups.util.GFLogWriter;

/*
 * Implementation of QuorumChecker interface using JGroups artifacts
 * @author Bruce Schuchardt
 * @since 8.1 11/2014
 */
public class QuorumCheckerImpl implements QuorumChecker {
  /**
   * the last view before a Forced Disconnect
   */
  private View lastView;
  /**
   * The old system's membership socket
   */
  private volatile DatagramSocket sock;
  /**
   * A boolean to stop the pingResponder thread
   */
  private AtomicBoolean stopper = new AtomicBoolean();
  /**
   * The thread that responds to ping requests from other members
   */
  private Thread pingResponder;
  /**
   * The jgroups network partition threshold percentage
   */
  private int partitionThreshold;
  
  /**
   * ping-pong responses received
   */
  private Set receivedAcks;
  
  /**
   * map converting from SocketAddresses to member IDs
   */
  private Map addressConversionMap;
  
  /**
   * Whether the quorum checker is currently suspended
   */
  private volatile boolean suspended;
  
  /**
   * Whether a quorum has been reached
   * guardedby this
   */
  private boolean quorumAchieved;
  
  
  @Override
  public void suspend() {
    this.suspended = true;
  }
  
  @Override
  public void resume() {
    this.suspended = false;
  }
  

  @Override
  public synchronized boolean checkForQuorum(long timeout, LogWriter debugLogger)
    throws InterruptedException {
    
    if (this.quorumAchieved) {
      return true;
    }
    
    if (this.sock == null || this.sock.isClosed()) {
      if (debugLogger != null && debugLogger.fineEnabled()) {
        debugLogger.fine("quorum check: UDP socket is closed.  Unable to perform a quorum check");
      }
      return false;
    }
    
    boolean wasSuspended = this.suspended;
    if (this.suspended) {
      this.suspended = false;
    }
    
    
    byte[] buffer = new byte[] { 'p', 'i', 'n', 'g' };
    
    
    if (debugLogger != null && debugLogger.fineEnabled()) {
      debugLogger.fine("beginning quorum check with " + this);
    }
    try {
      // send a ping message to each member and read pong responses
      Vector members = this.lastView.getMembers();
      for (int i=0; i= lossThreshold);
      return this.quorumAchieved;

    } finally {
      if (wasSuspended) {
        this.suspended = true;
      }
    }
  }


  @Override
  public Object getMembershipInfo() {
    if (this.sock == null || this.sock.isClosed()) {
      return null;
    }
    return this.sock;
  }
  
  /**
   * Create a new QuorumCheckerImpl.  It must be initialized with initialize() before
   * it can be used for quorum checks
   */
  protected QuorumCheckerImpl(View jgView, int partitionThreshold, DatagramSocket jgSock) {
    this.sock = jgSock;
    this.lastView = jgView;
    this.partitionThreshold = partitionThreshold;
  }

  
  protected void initialize() {
    if (this.sock == null  ||  this.sock.isClosed()) {
      return;
    }
    receivedAcks = new ConcurrentHashSet(this.lastView.size());
    addressConversionMap = new ConcurrentHashMap(this.lastView.size());
    Vector members = this.lastView.getMembers();
    for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy