gash.impl.raft.manager.HeartbeatData.java Source code

Java tutorial

Introduction

Here is the source code for gash.impl.raft.manager.HeartbeatData.java

Source

/*
 * copyright 2014, gash
 * 
 * Gash 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 gash.impl.raft.manager;

import gash.router.server.ServerOpUtil;
import gash.router.server.edges.EdgeList;
import gash.router.server.edges.EdgeMonitor;
import io.netty.channel.Channel;

import java.net.SocketAddress;

/**
 * This class contains the connection information for establishing a connection
 * to the specified host/port and the status of the heartbeats.
 * 
 * Given Nodes A and B, forming an edge AB. Who owns the edge between A and B?
 * 
 * In this design A does however, node B will send a heartbeatMgr to A rather
 * than A pinging node B. Think of this in the context of a client-server
 * relationship: The server (B) wants to know if the client (A) is still able to
 * receive a reply. This is only an example to show AB. Clients (i.e. external
 * or higher level layers) do not create heartbeat connections. These HBs are
 * for server-to-server monitoring.
 * 
 * 
 * As a result, the heartbeatMgr will keep the connection between the two nodes
 * active. On connection loss, the emitting node (i.e. node B) will wait for the
 * connection to be re-established before sending HB messages.
 * 
 * 
 * @author gash
 * 
 */
public class HeartbeatData {

    public static final int sWeakThresholdDefault = 2;
    public static final int sFailureThresholdDefault = 4;
    public static final int sFailureToSendThresholdDefault = 10;
    public static final int sBeatIntervalDefault = 10000; // msec

    private int nodeId;
    private String host;
    private Integer port;
    private Integer mgmtport;
    private BeatStatus status = BeatStatus.Unknown;
    private int beatInterval = sBeatIntervalDefault;
    private int weakTheshold = sWeakThresholdDefault;
    private int failureThreshold = sFailureThresholdDefault;
    private int failures; // TODO should be atomic
    private int failuresOnSend;
    private long initTime;
    private long lastBeat;
    private long lastBeatSent;
    private long lastFailed;

    // the connection
    public SocketAddress sa;

    public HeartbeatData(int nodeId, String host, Integer port, Integer mgmtport) {
        this.nodeId = nodeId;
        this.host = host;
        this.port = port;
        this.mgmtport = mgmtport;
    }

    /**
     * the management channel
     * 
     * @return
     */
    public Channel getChannel() {
        return ServerOpUtil.GetConnectionChannel(nodeId);

    }

    /**
     * @deprecated don't use!
     * @param channel
     */
    public void setChannelXX(Channel channel) {
        // ConnectionManager.addConnection(nodeId, channel);
    }

    public Integer getMgmtport() {
        return mgmtport;
    }

    public void setMgmtport(Integer mgmtport) {
        this.mgmtport = mgmtport;
    }

    /**
     * a heartbeatMgr may not be active (established) on initialization so, we
     * need to provide a way to initialize the metadata from the connection
     * data.
     * 
     * This is the primary way the connection manager in populated with
     * channels/connections
     * 
     * @param channel
     *            The newly established channel (management!)
     * @param sa
     * @param nodeId
     *            the node ID of the channel
     */
    public void setConnection(Channel channel, SocketAddress sa, Integer nodeId) {
        //EdgeList.a
        //ConnectionManager.addConnection(nodeId, channel, true);
        this.sa = sa;
    }

    /**
     * clear/reset internal tracking information and connection. The
     * host/port/ID are retained.
     */
    public void clearAll() {
        clearHeartData();
        initTime = 0;
        lastBeat = 0;
        lastBeatSent = 0;
        lastFailed = 0;
        failures = 0;
        failuresOnSend = 0;
        status = BeatStatus.Unknown;
    }

    public void incrementFailures() {
        failures++;
    }

    public void incrementFailuresOnSend() {
        failuresOnSend++;
    }

    public int getFailuresOnSend() {
        return failuresOnSend;
    }

    public void setFailuresOnSend(int failuresOnSend) {
        this.failuresOnSend = failuresOnSend;
    }

    public long getLastBeatSent() {
        return lastBeatSent;
    }

    public void setLastBeatSent(long lastBeatSent) {
        this.lastBeatSent = lastBeatSent;
    }

    public int getFailures() {
        return failures;
    }

    public void setFailures(int failures) {
        this.failures = failures;
    }

    public void clearHeartData() {
        // TODO close the request/public channels
        // TODO if we attempt o reconnect this should be removed
        if (ServerOpUtil.GetConnectionChannel(nodeId) != null)
            ServerOpUtil.GetConnectionChannel(nodeId).close();

        //EdgeList.
        //ConnectionManager.removeConnection(nodeId, true);
        sa = null;
    }

    /**
     * verify the connection is good and if not determine if it should be
     * disabled.
     * 
     * @return
     */
    public boolean isGood() {
        if (status == BeatStatus.Active || status == BeatStatus.Weak) {
            Channel ch = ServerOpUtil.GetConnectionChannel(nodeId);
            boolean rtn = ch.isOpen() && ch.isWritable();
            if (!rtn) {
                // TODO how to use the weakThreshold and status

                lastFailed = System.currentTimeMillis();
                failures++;
                if (failures >= failureThreshold)
                    status = BeatStatus.Failed;
                else if (failures >= weakTheshold)
                    status = BeatStatus.Weak;
            } else {
                failures = 0;
                lastFailed = 0;
            }

            return rtn;
        } else
            return false;
    }

    /**
     * An assigned unique key (node ID) to the remote connection
     * 
     * @return
     */
    public int getNodeId() {
        return nodeId;
    }

    public void setNodeId(int nodeId) {
        this.nodeId = nodeId;
    }

    /**
     * The host to connect to
     * 
     * @return
     */
    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    /**
     * The port the remote connection is listening to
     * 
     * @return
     */
    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public BeatStatus getStatus() {
        return status;
    }

    public void setStatus(BeatStatus status) {
        this.status = status;
    }

    public int getWeakTheshold() {
        return weakTheshold;
    }

    public void setWeakTheshold(int weakTheshold) {
        this.weakTheshold = weakTheshold;
    }

    public int getFailureThreshold() {
        return failureThreshold;
    }

    public void setFailureThreshold(int failureThreshold) {
        this.failureThreshold = failureThreshold;
    }

    public long getInitTime() {
        return initTime;
    }

    public void setInitTime(long initTime) {
        this.initTime = initTime;
    }

    public long getLastBeat() {
        return lastBeat;
    }

    public void setLastBeat(long lastBeat) {
        this.lastBeat = lastBeat;
    }

    public long getLastFailed() {
        return lastFailed;
    }

    public void setLastFailed(long lastFailed) {
        this.lastFailed = lastFailed;
    }

    public int getBeatInterval() {
        return beatInterval;
    }

    public void setBeatInterval(int beatInterval) {
        this.beatInterval = beatInterval;
    }

    public enum BeatStatus {
        Unknown, Init, Active, Weak, Failed
    }
}