/* * Copyright 2008-2009 the original author or authors. * * 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. */ package net.hasor.land.node; import io.netty.util.internal.ConcurrentSet; import net.hasor.core.EventListener; import net.hasor.core.Init; import net.hasor.core.Inject; import net.hasor.land.bootstrap.LandContext; import net.hasor.land.domain.LandEvent; import net.hasor.land.domain.ServerStatus; import net.hasor.land.utils.TermUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; /** * 当前服务器节点信息 * * @version : 2016年09月10日 * @author 赵永春(zyc@hasor.net) */ public class ServerNode implements EventListener<Object>, Operation { protected Logger logger = LoggerFactory.getLogger(getClass()); @Inject private LandContext landContext = null; private List<NodeData> allNodes = null; //所有服务器节点 private Set<String> supporterVote = null; //支持者的选票 // private final Object lock = new Object(); private ServerStatus status = null; //当前状态 private String currentTerm = null; //当前任期 private String votedFor = null; //得票候选人ID private long lastHeartbeat = 0; //最后一次来自Leader的心跳时间 // // // /** 当前条目ID(已递交,已生效) */ public String getCurrentTerm() { return currentTerm; } /** 当前服务器的选票投给了谁 */ public String getVotedFor() { return votedFor; } /** 当前服务器节点状态 */ public ServerStatus getStatus() { return status; } /** 最后一次 Leader 发来的心跳时间 */ public long getLastHeartbeat() { return lastHeartbeat; } /** 获取所有在线状态的节点 */ public List<NodeData> getOnlineNodes() { return allNodes; } // // // @Init public void init() throws URISyntaxException { // this.currentTerm = "0"; this.votedFor = null; this.status = ServerStatus.Follower; this.landContext.addVotedListener(this); this.landContext.addStatusListener(this); // // .添加节点 this.allNodes = new ArrayList<NodeData>(); Collection<String> serverIDs = this.landContext.getServerIDs(); for (String serverID : serverIDs) { this.allNodes.add(new NodeData(serverID, this.landContext)); } // this.supporterVote = new ConcurrentSet<String>(); } // // // @Override public void onEvent(String event, Object eventData) throws Throwable { if (eventData == null) { return; } if (LandEvent.ServerStatus.equalsIgnoreCase(event)) { this.status = (ServerStatus) eventData; } if (LandEvent.VotedFor_Event.equalsIgnoreCase(event)) { this.votedFor = (String) eventData; } } public void lockRun(RunLock runnable) { synchronized (this.lock) { runnable.run(this); } } @Override public boolean testVote(String serverID) { return this.supporterVote.contains(serverID); } // // // /** Term 自增 */ public void incrementAndGetTerm() { this.currentTerm = TermUtils.incrementAndGet(this.currentTerm); } /** Term 更新成比自己大的那个 */ public boolean updateTermTo(String remoteTerm) { if (TermUtils.gtFirst(this.currentTerm, remoteTerm)) { this.currentTerm = remoteTerm; return true; } return false; } /** 更新最后一次收到 Leader 的心跳时间 */ public void newLastLeaderHeartbeat() { this.lastHeartbeat = System.currentTimeMillis(); } @Override public void applyVoted(String serverID, boolean voteGranted) { if (voteGranted) { this.supporterVote.add(serverID); } else { this.supporterVote.remove(serverID); } } @Override public void clearVoted() { this.supporterVote.clear(); } }