Files
scandocs/uni/masterarbeit/source/moversight/fd/partition/timer/PartitionTimer.cc
2014-06-30 13:58:10 +02:00

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;
}
};
};