| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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 com.google.code.gossip.manager.impl; |
| |
| import java.util.List; |
| |
| import com.google.code.gossip.GossipMember; |
| import com.google.code.gossip.GossipService; |
| import com.google.code.gossip.LocalGossipMember; |
| import com.google.code.gossip.RemoteGossipMember; |
| import com.google.code.gossip.manager.GossipManager; |
| import com.google.code.gossip.manager.PassiveGossipThread; |
| |
| public class OnlyProcessReceivedPassiveGossipThread extends PassiveGossipThread { |
| |
| public OnlyProcessReceivedPassiveGossipThread(GossipManager gossipManager) { |
| super(gossipManager); |
| } |
| |
| /** |
| * Merge remote list (received from peer), and our local member list. Simply, we must update the |
| * heartbeats that the remote list has with our list. Also, some additional logic is needed to |
| * make sure we have not timed out a member and then immediately received a list with that member. |
| * |
| * @param gossipManager |
| * @param senderMember |
| * @param remoteList |
| */ |
| protected void mergeLists(GossipManager gossipManager, RemoteGossipMember senderMember, |
| List<GossipMember> remoteList) { |
| |
| //if the person sending to us is in the dead list consider them up |
| for (LocalGossipMember i : gossipManager.getDeadList()){ |
| if (i.getId().equals(senderMember.getId())){ |
| System.out.println(gossipManager.getMyself() +" caught a live one!"); |
| LocalGossipMember newLocalMember = new LocalGossipMember(senderMember.getHost(), |
| senderMember.getPort(), senderMember.getId(), senderMember.getHeartbeat(), |
| gossipManager, gossipManager.getSettings().getCleanupInterval()); |
| gossipManager.revivieMember(newLocalMember); |
| newLocalMember.startTimeoutTimer(); |
| } |
| } |
| for (GossipMember remoteMember : remoteList) { |
| if (remoteMember.getId().equals(gossipManager.getMyself().getId())) { |
| continue; |
| } |
| if (gossipManager.getMemberList().contains(remoteMember)) { |
| LocalGossipMember localMember = gossipManager.getMemberList().get( |
| gossipManager.getMemberList().indexOf(remoteMember)); |
| if (remoteMember.getHeartbeat() > localMember.getHeartbeat()) { |
| localMember.setHeartbeat(remoteMember.getHeartbeat()); |
| localMember.resetTimeoutTimer(); |
| } |
| } else if (!gossipManager.getMemberList().contains(remoteMember) |
| && !gossipManager.getDeadList().contains(remoteMember) ){ |
| LocalGossipMember newLocalMember = new LocalGossipMember(remoteMember.getHost(), |
| remoteMember.getPort(), remoteMember.getId(), remoteMember.getHeartbeat(), |
| gossipManager, gossipManager.getSettings().getCleanupInterval()); |
| gossipManager.createOrRevivieMember(newLocalMember); |
| newLocalMember.startTimeoutTimer(); |
| } else { |
| if (gossipManager.getDeadList().contains(remoteMember)) { |
| LocalGossipMember localDeadMember = gossipManager.getDeadList().get( |
| gossipManager.getDeadList().indexOf(remoteMember)); |
| if (remoteMember.getHeartbeat() > localDeadMember.getHeartbeat()) { |
| LocalGossipMember newLocalMember = new LocalGossipMember(remoteMember.getHost(), |
| remoteMember.getPort(), remoteMember.getId(), remoteMember.getHeartbeat(), |
| gossipManager, gossipManager.getSettings().getCleanupInterval()); |
| gossipManager.revivieMember(newLocalMember); |
| newLocalMember.startTimeoutTimer(); |
| GossipService.LOGGER.debug("Removed remote member " + remoteMember.getAddress() |
| + " from dead list and added to local member list."); |
| } else { |
| GossipService.LOGGER.debug("me " + gossipManager.getMyself()); |
| GossipService.LOGGER.debug("sender " + senderMember); |
| GossipService.LOGGER.debug("remote " + remoteList); |
| GossipService.LOGGER.debug("live " + gossipManager.getMemberList()); |
| GossipService.LOGGER.debug("dead " + gossipManager.getDeadList()); |
| } |
| } else { |
| GossipService.LOGGER.debug("me " + gossipManager.getMyself()); |
| GossipService.LOGGER.debug("sender " + senderMember); |
| GossipService.LOGGER.debug("remote " + remoteList); |
| GossipService.LOGGER.debug("live " + gossipManager.getMemberList()); |
| GossipService.LOGGER.debug("dead " + gossipManager.getDeadList()); |
| //throw new IllegalArgumentException("wtf"); |
| } |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| old comment section: |
| // If a member is restarted the heartbeat will restart from 1, so we should check |
| // that here. |
| // So a member can become from the dead when it is either larger than a previous |
| // heartbeat (due to network failure) |
| // or when the heartbeat is 1 (after a restart of the service). |
| // TODO: What if the first message of a gossip service is sent to a dead node? The |
| // second member will receive a heartbeat of two. |
| // TODO: The above does happen. Maybe a special message for a revived member? |
| // TODO: Or maybe when a member is declared dead for more than |
| // _settings.getCleanupInterval() ms, reset the heartbeat to 0. |
| // It will then accept a revived member. |
| // The above is now handle by checking whether the heartbeat differs |
| // _settings.getCleanupInterval(), it must be restarted. |
| */ |
| |
| /* |
| // The remote member is back from the dead. |
| // Remove it from the dead list. |
| // gossipManager.getDeadList().remove(localDeadMember); |
| // Add it as a new member and add it to the member list. |
| */ |