232 lines
7.9 KiB
C++
232 lines
7.9 KiB
C++
/*
|
|
* File: PartitionTimer.cc
|
|
* Author: gschneid
|
|
*
|
|
* Created on August 8, 2012, 10:17 AM
|
|
*/
|
|
|
|
#include "PartitionTimer.h"
|
|
|
|
#include "Moversight.h"
|
|
#include "Dispatcher.h"
|
|
#include "MoversightTimerSettings.h"
|
|
#include "fd/partition/PartitionDetector.h"
|
|
|
|
namespace ubeeme {
|
|
namespace moversight {
|
|
|
|
#undef DEBUG
|
|
#define DEBUG(msg) if ( pd.module.isPrintDebugNFD()) MOV_DEBUG << "PT@" << pd.dispatcher.getLocalID() << " "<<msg<<endl;
|
|
|
|
/**
|
|
* @brief Creates a Hello Timer (type = PARTITION_TIMER, name= PartitionTimer, timeout= partitionTimeout)
|
|
* @param aPd the PartitionDetector, which owns this timer instance
|
|
*/
|
|
PartitionTimer::PartitionTimer(PartitionDetector & aPd) : MoversightTimer(aPd), reReachablePeerID(UNDEFINED_PEER_ID), partitionTimerType(PT_UNDEFINED), pd(aPd) {
|
|
#if OMNETPP
|
|
setName("PARTITION_TIMER");
|
|
#endif
|
|
setTimeout(PARTITION_TIMEOUT);
|
|
|
|
}//End PartitionTimer
|
|
|
|
/**
|
|
* @brief Copy constructor.
|
|
* @param other The instance to copy.
|
|
*/
|
|
PartitionTimer::PartitionTimer(const PartitionTimer& other) : MoversightTimer(other), reReachablePeerID(other.reReachablePeerID), partitionTimerType(other.partitionTimerType), pd(other.pd) {
|
|
#if OMNETPP
|
|
setName(other.getName());
|
|
#endif
|
|
MoversightTimer::operator=(other);
|
|
//setTimeout(other.getTimeout());
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
PartitionTimer::~PartitionTimer() {
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief If the timer is fired, this method is called and the timer
|
|
* handled.
|
|
*/
|
|
void
|
|
PartitionTimer::timeout() {
|
|
dynamic_cast<PartitionDetector&> (service).handlePartitionTimer(this);
|
|
}
|
|
|
|
/**
|
|
* @brief A duplicate method. Duplicates the current timer.
|
|
* @return A reference to the new created timer.
|
|
*/
|
|
PartitionTimer*
|
|
PartitionTimer::dup() {
|
|
return new PartitionTimer(*this);
|
|
}
|
|
|
|
/**
|
|
* Method returning the type of the partitionTimer, needed for the different types of the partitionDetection.
|
|
* @return True if it is Mandatory, false if optional.
|
|
*/
|
|
bool
|
|
PartitionTimer::isMandatory() {
|
|
return (partitionTimerType == PT_MANDATORY) ? true : false;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the type of the timer. To be sure what to do, when timeout happens.
|
|
* @param flag The value to set the type: if true: MANDATORY, OPTIONAL else.
|
|
*/
|
|
void
|
|
PartitionTimer::setIsMandatory(bool flag) {
|
|
if (flag) {
|
|
partitionTimerType = PT_MANDATORY;
|
|
}
|
|
else {
|
|
partitionTimerType = PT_OPTIONAL;
|
|
}//End else
|
|
}
|
|
|
|
/**
|
|
* @brief Method that updates the queues after the partitionDetector signals the reception of a NDMC.
|
|
* If the peer that responded is still on the non-reachable queue, remove it from there and add it to
|
|
* the reachable queue.
|
|
* @param foundPeer The peerId of the peer who responded with a NDMC.
|
|
* @throws PeerNotFoundException if the given foundPeerID cannot be found in the nonreachable list.
|
|
*/
|
|
void
|
|
PartitionTimer::markAsReachable(PeerID foundPeer) {
|
|
|
|
if (nonReachablePeers.contains(foundPeer)) {
|
|
nonReachablePeers.remove(foundPeer);
|
|
reachablePeers.add(foundPeer, pd.getLocalPeer().isMaster());
|
|
}
|
|
else {
|
|
throw PeerNotFoundException("Peer cannot be found in the nonReachableList!!");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief If a Peer loses connection, this is happening by a signal from a deeper layer. Means
|
|
* it's definite that the peer has lost its connection. Adding all the other peers to the reachable list,
|
|
* so that we can handle this.
|
|
* @param lostPeerID The peer who has lost its connection.
|
|
*/
|
|
void
|
|
PartitionTimer::updateDueToConnectionLoss(PeerID lostPeerID) {
|
|
for (size_t i = 0; i < nonReachablePeers.size(); i++) {
|
|
PeerID pID = nonReachablePeers.getKey(i);
|
|
if (pID != lostPeerID) {
|
|
nonReachablePeers.remove(pID);
|
|
reachablePeers.add(pID, nonReachablePeers.get(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Method that adds a PeerIdList to the given unreachable queue.
|
|
* @param peerSet The PeerIDList to add.
|
|
*/
|
|
void
|
|
PartitionTimer::addingPeerSetToNonReachableList(PeerIDList peerSet) {
|
|
for (size_t i = 0; i < peerSet.size(); i++) {
|
|
PeerID pID = peerSet.get(i);
|
|
nonReachablePeers.add(pID, pd.getMembershipService().getPeer(pID).isMaster());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Initialise method that initially adds the local slaves in the cluster
|
|
* and all the masters to the unreachable-queue and removes itself.
|
|
*/
|
|
void
|
|
PartitionTimer::setNonReachablePeersFromMR() {
|
|
PeerIDList peerSet = pd.getMembershipService().getClusterAndMasterPeerIDList(pd.getLocalPeer());
|
|
nonReachablePeers.clear();
|
|
addingPeerSetToNonReachableList(peerSet);
|
|
}
|
|
|
|
/**
|
|
* @brief Method that returns the PeerIDlist of the peers still in the nonreachable queue.
|
|
* @return PeerIDList of all the peers still on the unreachable-queue.
|
|
*/
|
|
PeerIDList
|
|
PartitionTimer::getNonReachablePeerIDList() {
|
|
return nonReachablePeers.getPeerIDList();
|
|
}
|
|
|
|
/**
|
|
* @brief Method that returns the PeerIDList of the peers that are reachable.
|
|
* @return PeerIDList of all the peers the peer can reach.
|
|
*/
|
|
PeerIDList
|
|
PartitionTimer::getReachablePeerIDList() {
|
|
return reachablePeers.getPeerIDList();
|
|
}
|
|
|
|
/**
|
|
* @brief Method that returns the PeerIDList of the given master peers still in the nonreachable queue.
|
|
* @return PeerIDList of all the masters still on the unreachable queue.
|
|
*/
|
|
PeerIDList
|
|
PartitionTimer::getNonReachableMasters() {
|
|
return nonReachablePeers.getMastersOnly();
|
|
}
|
|
|
|
/**
|
|
* @brief Method that returns whether the nonreachablequeue is empty or not.
|
|
* @return true if the nonreachable queue is empty, false if not.
|
|
*/
|
|
bool
|
|
PartitionTimer::isNonReachableQueueEmpty() {
|
|
if (nonReachablePeers.size() == 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Method to update the reachable and nonreachable list when a peer got disconnected.
|
|
* @param pId - the peer who is no longer member of the group.
|
|
*/
|
|
void
|
|
PartitionTimer::updateListsDueToDisconnectedPeer(PeerID pId) {
|
|
|
|
peersDisconnectedDuringPartition.add(pId);
|
|
reachablePeers.remove(pId);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the peers of the group disconnected during the ongoing partition.
|
|
* @return The peerIDList of peers no longer member of the group.
|
|
*/
|
|
PeerIDList
|
|
PartitionTimer::getDisconnectedPeers() {
|
|
return peersDisconnectedDuringPartition;
|
|
}
|
|
|
|
/**
|
|
* Getting the rereachablePeer in the other partition.
|
|
* @return PeerID of the peer we could reach again.
|
|
*/
|
|
PeerID &
|
|
PartitionTimer::getReReachablePeerID() {
|
|
return reReachablePeerID;
|
|
}
|
|
|
|
/**
|
|
* @brief Setting the rereachablePeer in the other partition.
|
|
* @param pID PeerID of the peer we could reach again.
|
|
*/
|
|
void
|
|
PartitionTimer::setReReachablePeerID(PeerID pID) {
|
|
reReachablePeerID = pID;
|
|
}
|
|
|
|
};
|
|
};
|