Bamboo Class Reference

#include <Bamboo.h>

Inheritance diagram for Bamboo:

BasePastry BaseOverlay BaseRpc TopologyVis RpcListener

List of all members.


Detailed Description

Pastry overlay module.

Author:
Felix Palmen
See also:
BaseOverlay

Public Member Functions

virtual ~Bamboo ()
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void handleTimerEvent (cMessage *msg)
 Processes "timer" self-messages.
virtual void handleUDPMessage (BaseOverlayMessage *msg)
 Processes messages from underlay.
void handleStateMessage (PastryStateMessage *msg)
 processes state messages, merging with own state tables

Protected Member Functions

virtual void changeState (int toState)
 changes node state
virtual void lookupFinished (AbstractLookup *lookup)

Private Member Functions

void doLeafsetMaintenance (void)
 periodically repairs the leafset by pushing it to and pulling it from from a random live leafset node
void doGlobalTuning (void)
 periodically repairs the routing table by performing random lookups
bool handleFailedNode (const TransportAddress &failed)
 notifies leafset and routingtable of a failed node and sends out a repair request if possible
void checkProxCache (void)
 checks whether proxCache is complete, takes appropriate actions depending on the protocol state
virtual void joinOverlay ()
 Join the overlay with a given nodeID in thisNode.key.

Private Attributes

double leafsetMaintenanceTimeoutAmount
double globalTuningTimeoutAmount
cMessage * leafsetMaintenanceTimeout
cMessage * globalTuningTimeout

Friends

class BambooLookupListener

Constructor & Destructor Documentation

Bamboo::~Bamboo (  )  [virtual]

00040 {
00041 
00042     // destroy self timer messages
00043     cancelAndDelete(joinTimeout);
00044     cancelAndDelete(readyWait);
00045     cancelAndDelete(repairTaskTimeout);
00046     cancelAndDelete(leafsetMaintenanceTimeout);
00047     cancelAndDelete(globalTuningTimeout);
00048 
00049     purgeVectors();
00050 }


Member Function Documentation

void Bamboo::initializeOverlay ( int  stage  )  [virtual]

Initializes derived-class-attributes.


Initializes derived-class-attributes, called by BaseOverlay::initialize(). By default this method is called once. If more stages are needed one can overload numInitStages() and add more stages.

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

00070 {
00071     if ( stage != MIN_STAGE_OVERLAY )
00072         return;
00073 
00074     // Bamboo provides KBR services
00075     kbr = true;
00076 
00077     baseInit();
00078 
00079     repairTaskTimeoutAmount = par("repairTaskTimeoutAmount");
00080     leafsetMaintenanceTimeoutAmount = par("leafsetMaintenanceTimeoutAmount");
00081     globalTuningTimeoutAmount = par("globalTuningTimeoutAmount");
00082 
00083     joinTimeout = new cMessage("joinTimeout");
00084     readyWait = new cMessage("readyWait");
00085     //joinUpdateWait = new cMessage("joinUpdateWait");
00086 
00087     repairTaskTimeout = new cMessage("repairTaskTimeout");
00088     leafsetMaintenanceTimeout = new cMessage("leafsetMaintenanceTimeout");
00089     globalTuningTimeout = new cMessage("globalTuningTimeout");
00090 
00091     sendPullFlag = true;
00092 
00093 }

void Bamboo::handleTimerEvent ( cMessage *  msg  )  [virtual]

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

00160 {
00161 
00162     if (msg->isName("joinTimeout")) {
00163         EV << "Pastry: join timeout expired, restarting..." << endl;
00164         joinOverlay();
00165     } else if (msg->isName("readyWait")) {
00166         if (partialJoinPath) {
00167             RECORD_STATS(joinPartial++);
00168             sort(stReceived.begin(), stReceived.end(), stateMsgIsSmaller);
00169 
00170             // start pinging the nodes found in the first state message:
00171             stReceivedPos = stReceived.begin();
00172             stateCache = *stReceivedPos;
00173             EV << "Pastry: joining despite some missing STATE messages."
00174                << endl;
00175             pingNodes();
00176         } else {
00177             EV << "Pastry: timeout waiting for missing state messages in JOIN "
00178                 "state, restarting..." << endl;
00179             joinOverlay();
00180         }
00181     }
00182     else if (msg->isName("repairTaskTimeout")) {
00183         EV << "Pastry: starting routing table maintenance" << endl;
00184         doRoutingTableMaintenance();
00185         scheduleAt(simTime()+repairTaskTimeoutAmount, repairTaskTimeout);
00186     }
00187     else if (msg->isName("leafsetMaintenanceTimeout")) {
00188         EV << "Pastry: starting leafset maintenance" << endl;
00189         doLeafsetMaintenance();
00190         scheduleAt(simTime()+leafsetMaintenanceTimeoutAmount, leafsetMaintenanceTimeout);
00191     }
00192     else if (msg->isName("globalTuningTimeout")) {
00193         EV << "Pastry: starting global tuning" << endl;
00194         doGlobalTuning();
00195         scheduleAt(simTime()+globalTuningTimeoutAmount, globalTuningTimeout);
00196     }
00197 }

void Bamboo::handleUDPMessage ( BaseOverlayMessage *  msg  )  [virtual]

Processes messages from underlay.

Parameters:
msg Message from UDP

Reimplemented from BaseOverlay.

00200 {
00201     PastryMessage* pastryMsg = check_and_cast<PastryMessage*>(msg);
00202     uint type = pastryMsg->getPastryMsgType();
00203 
00204     if (debugOutput) {
00205         EV << "Pastry: incoming message of type ";
00206         switch(type) {
00207         case PASTRY_MSG_STD:
00208             EV << "PASTRY_MSG_STD";
00209             break;
00210         case PASTRY_MSG_JOIN:
00211             EV << "PASTRY_MSG_JOIN";
00212             break;
00213         case PASTRY_MSG_STATE:
00214             EV << "PASTRY_MSG_STATE";
00215             break;
00216         case PASTRY_MSG_LEAFSET:
00217             EV << "PASTRY_MSG_LEAFSET";
00218             break;
00219         case PASTRY_MSG_LEAFSET_PULL:
00220             EV << "PASTRY_MSG_LEAFSET_PULL";
00221             break;
00222         case PASTRY_MSG_ROWREQ:
00223             EV << "PASTRY_MSG_ROWREQ";
00224             break;
00225         case PASTRY_MSG_RROW:
00226             EV << "PASTRY_MSG_RROW";
00227             break;
00228         case PASTRY_MSG_REQ:
00229             EV << "PASTRY_MSG_REQ";
00230             break;
00231         default:
00232             EV << "UNKNOWN (" << type <<")";
00233             break;
00234         }
00235         EV << endl;
00236     }
00237 
00238     switch (type) {
00239     case PASTRY_MSG_STD:
00240         opp_error("Pastry received PastryMessage of unknown type!");
00241         break;
00242     case PASTRY_MSG_JOIN:
00243 
00244         break;
00245 
00246     case PASTRY_MSG_LEAFSET: {
00247         PastryLeafsetMessage* lmsg =
00248             check_and_cast<PastryLeafsetMessage*>(pastryMsg);
00249         RECORD_STATS(leafsetReceived++; leafsetBytesReceived +=
00250             lmsg->byteLength());
00251 
00252         if (state == JOINING_2) {
00253             cancelEvent(joinTimeout);
00254         }
00255 
00256         if ((state == JOINING_2) || (state == READY)) {
00257             handleLeafsetMessage(lmsg, true);
00258         } else {
00259             delete lmsg;
00260         }
00261     }
00262         break;
00263 
00264     case PASTRY_MSG_LEAFSET_PULL: {
00265         PastryLeafsetMessage* lmsg =
00266             check_and_cast<PastryLeafsetMessage*>(pastryMsg);
00267         RECORD_STATS(leafsetReceived++; leafsetBytesReceived +=
00268             lmsg->byteLength());
00269 
00270         if (state == READY) {
00271 
00272             sendLeafset(lmsg->getSendStateTo());
00273             handleLeafsetMessage(lmsg, true);
00274 
00275         } else {
00276             delete lmsg;
00277         }
00278     }
00279         break;
00280 
00281     case PASTRY_MSG_ROWREQ: {
00282 
00283         PastryRoutingRowRequestMessage* rtrmsg =
00284             check_and_cast<PastryRoutingRowRequestMessage*>(pastryMsg);
00285         RECORD_STATS(routingTableReqReceived++; routingTableReqBytesReceived +=
00286             rtrmsg->byteLength());
00287         if (state == READY)
00288             if (rtrmsg->getRow() == -1)
00289                 sendRoutingRow(rtrmsg->getSendStateTo(), routingTable->getLastRow());
00290                 else if (rtrmsg->getRow() > routingTable->getLastRow())
00291                     EV << "Pastry: received request for nonexistent routing"
00292                        << "table row, dropping message!" << endl;
00293                 else sendRoutingRow(rtrmsg->getSendStateTo(), rtrmsg->getRow());
00294         else
00295             EV << "Pastry: received routing table request before reaching "
00296                << "READY state, dropping message!" << endl;
00297        delete rtrmsg;
00298     }
00299         break;
00300 
00301     case PASTRY_MSG_RROW: {
00302         PastryRoutingRowMessage* rtmsg =
00303             check_and_cast<PastryRoutingRowMessage*>(pastryMsg);
00304         RECORD_STATS(routingTableReceived++; routingTableBytesReceived +=
00305             rtmsg->byteLength());
00306 
00307         if (state == READY) {
00308 
00309             uint nodesPerRow = routingTable->nodesPerRow;
00310             PastryStateMessage* stateMsg;
00311 
00312             stateMsg = new PastryStateMessage("STATE");
00313             stateMsg->setTimestamp(rtmsg->getTimestamp());
00314             stateMsg->setPastryMsgType(PASTRY_MSG_STATE);
00315             stateMsg->setStatType(MAINTENANCE_STAT);
00316             stateMsg->setSender(rtmsg->getSender());
00317             stateMsg->setLeafSetArraySize(0);
00318             stateMsg->setNeighborhoodSetArraySize(0);
00319             stateMsg->setRoutingTableArraySize(nodesPerRow);
00320 
00321             for (uint i = 0; i < nodesPerRow; i++) {
00322                 stateMsg->setRoutingTable(i, rtmsg->getRoutingTable(i));
00323             }
00324 
00325             handleStateMessage(stateMsg);
00326         }
00327 
00328         delete rtmsg;
00329     }
00330         break;
00331 
00332     case PASTRY_MSG_REQ: {
00333         PastryRequestMessage* lrmsg =
00334             check_and_cast<PastryRequestMessage*>(pastryMsg);
00335         handleRequestMessage(lrmsg);
00336     }
00337         break;
00338 
00339     case PASTRY_MSG_STATE: {
00340         PastryStateMessage* stateMsg =
00341             check_and_cast<PastryStateMessage*>(msg);
00342         RECORD_STATS(stateReceived++; stateBytesReceived +=
00343                      stateMsg->byteLength());
00344         handleStateMessage(stateMsg);
00345     }
00346         break;
00347     }
00348 }

void Bamboo::handleStateMessage ( PastryStateMessage *  msg  )  [virtual]

processes state messages, merging with own state tables

Parameters:
msg the pastry state message

Implements BasePastry.

Referenced by handleUDPMessage().

00447 {
00448     if (debugOutput) {
00449         EV << "Pastry::handleStateMessage() new STATE message to process "
00450            << static_cast<void*>(msg) << " in state " <<
00451             ((state == READY)?"READY":((state == JOINING_2)?"JOIN":"INIT"))
00452            << endl;
00453     }
00454 
00455     if (state == INIT) {
00456         EV << "Pastry: can't handle state messages until at least reaching "
00457             "JOIN state." << endl;
00458         delete msg;
00459         return;
00460     }
00461 
00462     PastryStateMsgHandle handle(msg);
00463 
00464     if (state == JOINING_2) {
00465         determineAliveTable(msg);
00466         leafSet->mergeState(msg, aliveTable);
00467         // merged state into leafset right now
00468         lastStateChange = simTime();
00469         newLeafs();
00470         updateTooltip();
00471 
00472         // no state message is processed right now, start immediately:
00473        stateCache = handle;
00474        pingNodes();
00475 
00476         return;
00477     }
00478 
00479     // determine aliveTable to prevent leafSet from merging nodes that are
00480     // known to be dead:
00481     determineAliveTable(msg);
00482     if (leafSet->mergeState(msg, aliveTable)) {
00483         // merged state into leafset right now
00484         lastStateChange = simTime();
00485         newLeafs();
00486         updateTooltip();
00487     }
00488     // in READY state, only ping nodes to get proximity metric:
00489     if (!stateCache.msg) {
00490         // no state message is processed right now, start immediately:
00491         stateCache = handle;
00492         pingNodes();
00493     } else {
00494         // enqueue message for later processing:
00495         stateCacheQueue.push(handle);
00496         prePing(msg);
00497     }
00498 }

void Bamboo::changeState ( int  toState  )  [protected, virtual]

changes node state

Parameters:
toState state to change to

Reimplemented from BasePastry.

Referenced by checkProxCache(), and joinOverlay().

00109 {
00110 
00111     baseChangeState(toState);
00112 
00113     switch (toState) {
00114     case INIT:
00115 
00116         break;
00117 
00118     case DISCOVERY:
00119 
00120         break;
00121 
00122     case JOINING_2:
00123 
00124     {
00125         PastryLeafsetMessage* msg = new PastryLeafsetMessage("Leafset");
00126          msg->setPastryMsgType(PASTRY_MSG_LEAFSET_PULL);
00127          msg->setStatType(MAINTENANCE_STAT);
00128          msg->setSender(thisNode);
00129          msg->setSendStateTo(thisNode);
00130          leafSet->dumpToStateMessage(msg);
00131          msg->setLength(PASTRYLEAFSET_L(msg));
00132          RECORD_STATS(leafsetSent++; leafsetBytesSent += msg->byteLength());
00133          std::vector<TransportAddress> sourceRoute;
00134          sourceRoute.push_back(bootstrapNode);
00135          sendToKey(thisNode.key, msg, 0/*1*/, sourceRoute);
00136      }
00137 
00138         break;
00139 
00140     case READY:
00141 
00142         // schedule routing table maintenance task
00143         cancelEvent(repairTaskTimeout);
00144         scheduleAt(simTime() + repairTaskTimeoutAmount, repairTaskTimeout);
00145         //EV << "local tuning scheduled for " << repairTaskTimeoutAmount << endl;
00146         //leaf2ask = NULL;
00147 
00148         cancelEvent(leafsetMaintenanceTimeout);
00149         //scheduleAt(simTime() + leafsetMaintenanceTimeoutAmount, leafsetMaintenanceTimeout);
00150         scheduleAt(simTime() + strToSimtime("200ms"), leafsetMaintenanceTimeout);
00151 
00152         cancelEvent(globalTuningTimeout);
00153         scheduleAt(simTime() + globalTuningTimeoutAmount, globalTuningTimeout);
00154 
00155         break;
00156     }
00157 }

void Bamboo::lookupFinished ( AbstractLookup lookup  )  [protected, virtual]

00501 {
00502     EV << "[BambooListener::lookupFinished()]\n";
00503     if (lookup->isValid()) {
00504             EV  << "    Lookup successful" << endl;
00505     } else {
00506             EV << "    Lookup failed" << endl;
00507     }
00508 
00509 }

void Bamboo::doLeafsetMaintenance ( void   )  [private]

periodically repairs the leafset by pushing it to and pulling it from from a random live leafset node

Referenced by handleTimerEvent().

00351 {
00352 
00353     const TransportAddress& ask = leafSet->getRandomNode();
00354     if (!ask.isUnspecified()) {
00355         sendLeafset(ask, true);
00356         EV << "Bamboo: leafset maintenance: pulling leafset from "
00357            << ask << endl;
00358     }
00359 
00360 }

void Bamboo::doGlobalTuning ( void   )  [private]

periodically repairs the routing table by performing random lookups

Referenced by handleTimerEvent().

00363 {
00364 
00365     OverlayKey newKey = OverlayKey::random();
00366     //OverlayKey OverlayKey::randomSuffix       (       uint     pos     )       const
00367 
00368     createLookup()->lookup(newKey, 1, 0, 0,
00369                  new BambooLookupListener(this));
00370 
00371 }

bool Bamboo::handleFailedNode ( const TransportAddress failed  )  [private, virtual]

notifies leafset and routingtable of a failed node and sends out a repair request if possible

Parameters:
failed the failed node
Returns:
true as long as local state is READY (signals lookup to try again)

Reimplemented from BaseOverlay.

00374 {
00375     if (state != READY) {
00376         return false;
00377     }
00378 
00379     if (failed.isUnspecified())
00380         opp_error("Bamboo::handleFailedNode(): failed is unspecified!");
00381 
00382     const TransportAddress& lsAsk = leafSet->failedNode(failed);
00383     /*const TransportAddress& rtAsk = */routingTable->failedNode(failed);
00384     neighborhoodSet->failedNode(failed);
00385 
00386     if (lsAsk.isUnspecified() && (! leafSet->isValid())) {
00387         EV << "Pastry: lost connection to the network, trying to re-join."
00388            << endl;
00389         joinOverlay();
00390         return false;
00391     }
00392 
00393     return true;
00394 }

void Bamboo::checkProxCache ( void   )  [private, virtual]

checks whether proxCache is complete, takes appropriate actions depending on the protocol state

Implements BasePastry.

00397 {
00398     if (state == JOINING_2) {
00399         changeState(READY);
00400         return;
00401     }
00402 
00403     // state == READY
00404     simtime_t now = simTime();
00405 
00406     // no cached STATE message?
00407     if (!(stateCache.msg && stateCache.prox)) return;
00408 
00409     // some entries not yet determined?
00410     if (find(stateCache.prox->pr_rt.begin(), stateCache.prox->pr_rt.end(),
00411              PASTRY_PROX_PENDING) != stateCache.prox->pr_rt.end()
00412         ) return;
00413     if (find(stateCache.prox->pr_ls.begin(), stateCache.prox->pr_ls.end(),
00414              PASTRY_PROX_PENDING) != stateCache.prox->pr_ls.end()
00415         ) return;
00416     if (find(stateCache.prox->pr_ns.begin(), stateCache.prox->pr_ns.end(),
00417              PASTRY_PROX_PENDING) != stateCache.prox->pr_ns.end()
00418         ) return;
00419 
00420     // merge info in own state tables
00421     // except leafset (was already handled in handleStateMessage)
00422     if (neighborhoodSet->mergeState(stateCache.msg, *stateCache.prox))
00423     lastStateChange = now;
00424     EV << "Merging nodes into routing table" << endl;
00425     if (routingTable->mergeState(stateCache.msg, *stateCache.prox)) {
00426         lastStateChange = now;
00427         EV << "merged nodes into routing table" << endl;
00428     }
00429 
00430     updateTooltip();
00431 
00432     delete stateCache.msg;
00433     stateCache.msg = NULL;
00434     delete stateCache.prox;
00435           stateCache.prox = NULL;
00436 
00437     // process next queued message:
00438     if (! stateCacheQueue.empty()) {
00439         stateCache = stateCacheQueue.front();
00440               stateCacheQueue.pop();
00441         pingNodes();
00442     }
00443 
00444 }

void Bamboo::joinOverlay (  )  [private, virtual]

Join the overlay with a given nodeID in thisNode.key.

Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.

Reimplemented from BaseOverlay.

Referenced by handleFailedNode(), and handleTimerEvent().

00096 {
00097     changeState(INIT);
00098 
00099     if (bootstrapNode.isUnspecified()) {
00100         // no existing pastry network -> first node of a new one
00101         changeState(READY);
00102     } else {
00103         // join existing pastry network
00104         changeState(JOINING_2);
00105     }
00106 }


Friends And Related Function Documentation

friend class BambooLookupListener [friend]

Referenced by doGlobalTuning().


Member Data Documentation

cMessage* Bamboo::leafsetMaintenanceTimeout [private]

cMessage* Bamboo::globalTuningTimeout [private]


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:05 2008 for ITM OverSim by  doxygen 1.5.5