#include <KBRTestApp.h>
Test application for KBR interface that sends periodically test messages to random keys or existing nodeIDs. The receiver does not send back any answer, but sender::evaluateDate() is called.
Public Member Functions | |
KBRTestApp () | |
~KBRTestApp () | |
Private Types | |
typedef std::vector< MsgHandle > | MsgHandleBuf |
Private Member Functions | |
void | initializeApp (int stage) |
initializes derived class-attributes | |
void | finishApp () |
collects statistical data of derived app | |
void | handleTimerEvent (cMessage *msg) |
processes self-messages | |
void | deliver (OverlayKey &key, cMessage *msg) |
Common API function: handles delivered messages from overlay. | |
void | forward (OverlayKey *key, cMessage **msg, NodeHandle *nextHopNode) |
Common API function: handles messages from overlay to be forwarded. | |
bool | checkSeen (const OverlayKey &key, int seqNum) |
Checks if a message was already seen before. | |
void | evaluateData (simtime_t timeDelay, int hopCount, long int bytes) |
Analyses and records measuring data handed over from nodes that previously had been the destination for a test message from this module, called by receiver::handleMessage() at sendermodule. | |
void | handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
void | handleLookupResponse (LookupResponse *msg) |
void | pingResponse (PingResponse *response, cPolymorphic *context, int rpcId, simtime_t rtt) |
virtual void | handleNodeLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed. | |
Private Attributes | |
double | mean |
mean time interval between sending test messages | |
double | deviation |
deviation of time interval | |
bool | activeNetwInitPhase |
is app active in network init phase? | |
bool | lookupNodeIds |
lookup only existing nodeIDs | |
bool | nodeIsLeavingSoon |
true if the node is going to be killed shortly | |
int | numDelivered |
number of delivered packets | |
int | bytesDelivered |
number of delivered bytes | |
int | numDropped |
int | bytesDropped |
cMessage * | testTimer |
uint | sequenceNumber |
int | msgHandleBufSize |
how many MsgHandles to store in circular buffer | |
MsgHandleBuf | mhBuf |
circular buffer of MsgHandles | |
MsgHandleBuf::iterator | mhBufBegin |
begin of circular buffer | |
MsgHandleBuf::iterator | mhBufNext |
next element to insert | |
MsgHandleBuf::iterator | mhBufEnd |
end of circular buffer | |
Classes | |
struct | MsgHandle |
type for storing seen messages in a circular buffer, holds OverlayKey of the sender and SequenceNumber More... |
typedef std::vector<MsgHandle> KBRTestApp::MsgHandleBuf [private] |
KBRTestApp::KBRTestApp | ( | ) |
KBRTestApp::~KBRTestApp | ( | ) |
void KBRTestApp::initializeApp | ( | int | stage | ) | [private, virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented from BaseApp.
00046 { 00047 if (stage != MIN_STAGE_APP) { 00048 return; 00049 } 00050 00051 lookupNodeIds = par("lookupNodeIds"); 00052 mean = par("testMsgInterval"); 00053 deviation = mean / 10; 00054 activeNetwInitPhase = par("activeNetwInitPhase"); 00055 msgHandleBufSize = par("msgHandleBufSize"); 00056 00057 numDelivered = 0; 00058 bytesDelivered = 0; 00059 WATCH(numDelivered); 00060 WATCH(bytesDelivered); 00061 00062 numDropped = 0; 00063 bytesDropped = 0; 00064 WATCH(numDropped); 00065 WATCH(bytesDropped); 00066 00067 sequenceNumber = 0; 00068 00069 nodeIsLeavingSoon = false; 00070 00071 // initialize circular buffer 00072 if (msgHandleBufSize > 0) { 00073 mhBuf.resize(msgHandleBufSize); 00074 mhBufBegin = mhBuf.begin(); 00075 mhBufEnd = mhBuf.end(); 00076 mhBufNext = mhBufBegin; 00077 } 00078 00079 #if 0 00080 bindToPort(1025); 00081 thisNode.port = 1025; 00082 #endif 00083 00084 // start periodic timer 00085 testTimer = new cMessage("KBRTestApp Timer"); 00086 scheduleAt(simulation.simTime() + truncnormal(mean, deviation), testTimer); 00087 }
void KBRTestApp::finishApp | ( | ) | [private, virtual] |
collects statistical data of derived app
Reimplemented from BaseApp.
00283 { 00284 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00285 00286 if (time != 0) { 00287 globalStatistics->addStdDev("KBRTestApp: Delivered Messages/s", 00288 numDelivered / time); 00289 globalStatistics->addStdDev("KBRTestApp: Delivered Bytes/s", 00290 bytesDelivered / time); 00291 globalStatistics->addStdDev("KBRTestApp: Dropped Messages/s", 00292 numDropped / time); 00293 globalStatistics->addStdDev("KBRTestApp: Dropped Bytes/s", 00294 bytesDropped / time); 00295 if (numOverlaySent != 0) { 00296 globalStatistics->addStdDev("KBRTestApp: KBR Delivery Ratio", 00297 (float)numDelivered / 00298 (float)numOverlaySent); 00299 } else { 00300 globalStatistics->addStdDev("KBRTestApp: KBR Delivery Ratio", 0); 00301 } 00302 } 00303 }
void KBRTestApp::handleTimerEvent | ( | cMessage * | msg | ) | [private, virtual] |
processes self-messages
method to handle self-messages should be overwritten in derived application if needed
msg | self-message |
Reimplemented from BaseApp.
00090 { 00091 if (msg == testTimer) { 00092 // schedule next timer event 00093 scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg); 00094 00095 // do nothing if the network is still in the initialization phase 00096 if ((!activeNetwInitPhase && underlayConfigurator->isInInitPhase()) 00097 || underlayConfigurator->isSimulationEndingSoon() 00098 || nodeIsLeavingSoon) { 00099 00100 return; 00101 } 00102 00103 OverlayKey destKey; 00104 if (lookupNodeIds) { 00105 destKey = bootstrapOracle->getBootstrapNode().key; 00106 // do nothing if there are currently no nodes in the network 00107 if (destKey.isUnspecified()) 00108 return; 00109 } else { 00110 // generate random destination key 00111 destKey = OverlayKey::random(); 00112 } 00113 00114 // create a 100 byte test message 00115 KBRTestMessage* testMsg = new KBRTestMessage("KBRTestMessage"); 00116 testMsg->setId(id()); 00117 testMsg->setSeqNum(sequenceNumber++); 00118 testMsg->setByteLength(100); 00119 testMsg->setMeasurementPhase(globalStatistics->isMeasuring()); 00120 00121 RECORD_STATS(globalStatistics->sentKBRTestAppMessages++); 00122 00123 callRoute(destKey, testMsg); 00124 00125 #if 0 00126 thisNode.port = 1025; 00127 NodeHandle handle = bootstrapOracle->getBootstrapNode(); 00128 handle.port = 1025; 00129 pingNode(handle, -1, -1, NULL, "TestPING", NULL, -1, UDP_TRANSPORT); 00130 00131 LookupCall* call = new LookupCall(); 00132 call->setLength(0); 00133 call->setKey(destKey); 00134 call->setNumSiblings(overlay->getMaxNumSiblings()); 00135 sendInternalRpcCall(OVERLAY_COMP, call); 00136 #endif 00137 00138 } 00139 }
void KBRTestApp::deliver | ( | OverlayKey & | key, | |
cMessage * | msg | |||
) | [private, virtual] |
Common API function: handles delivered messages from overlay.
method to handle decapsulated KBRdeliver messages from overlay module, should be overwritten in derived application
key | destination key | |
msg | delivered message |
Reimplemented from BaseApp.
00186 { 00187 KBRTestMessage* testMsg = check_and_cast<KBRTestMessage*>(msg); 00188 OverlayCtrlInfo* overlayCtrlInfo = 00189 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo()); 00190 00191 if (overlay->getThisNode().key.isUnspecified()) 00192 error("key"); 00193 00194 // check for duplicate 00195 if ((msgHandleBufSize > 0 ) 00196 && checkSeen(overlayCtrlInfo->getSrcNode().key, testMsg->getSeqNum())) { 00197 EV << "KBRTestApp: duplicate dropped." << std::endl; 00198 delete overlayCtrlInfo; 00199 delete testMsg; 00200 return; 00201 } 00202 00203 // Return statistical data to the sender. 00204 if (cModule* mod = simulation.module(testMsg->getId())) { 00205 if (KBRTestApp* sender = dynamic_cast<KBRTestApp*>(mod)) { 00206 if ((!lookupNodeIds) || (overlay->getThisNode().key == key)) { 00207 if (testMsg->getMeasurementPhase() == true) { 00208 sender->evaluateData((simTime() - testMsg->creationTime()), 00209 overlayCtrlInfo->getHopCount(), 00210 testMsg->byteLength()); 00211 } 00212 } else if(lookupNodeIds) { 00213 RECORD_STATS(numDropped++; 00214 bytesDropped += testMsg->byteLength()); 00215 EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().ip 00216 << " (" << overlay->getThisNode().key.toString(16) << ")]\n" 00217 << " Error: Lookup of NodeIDs and KBRTestMessage" 00218 << " received with different destKey!" 00219 << endl; 00220 } 00221 } 00222 } 00223 00224 EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().ip 00225 << " (" << overlay->getThisNode().key.toString(16) << ")]\n" 00226 << " Received \"" << testMsg->name() << "(seqNr: " 00227 << testMsg->getSeqNum() << ")\n" 00228 << " with destination key: " << key.toString(16) 00229 << endl; 00230 00231 delete overlayCtrlInfo; 00232 delete testMsg; 00233 }
void KBRTestApp::forward | ( | OverlayKey * | key, | |
cMessage ** | msg, | |||
NodeHandle * | nextHopNode | |||
) | [private, virtual] |
Common API function: handles messages from overlay to be forwarded.
method to handle decapsulated KBRdeliver messages from overlay module, should be overwritten in derived application if needed
key | destination key | |
msg | message to forward | |
nextHopNode | next hop |
Reimplemented from BaseApp.
00237 { 00238 KBRTestMessage* tempMsg = check_and_cast<KBRTestMessage*>(*msg); 00239 00240 tempMsg->setVisitedNodesArraySize(tempMsg->getVisitedNodesArraySize() + 1); 00241 tempMsg->setVisitedNodes(tempMsg->getVisitedNodesArraySize() - 1, 00242 overlay->getThisNode().ip); 00243 }
bool KBRTestApp::checkSeen | ( | const OverlayKey & | key, | |
int | seqNum | |||
) | [private] |
Checks if a message was already seen before.
If the sequence number of the message is new for the given sender key, it is stored in a circular buffer and false is returned.
key | the OverlayKey of the sender | |
seqNum | sequence number of the message to check |
Referenced by deliver().
00246 { 00247 MsgHandle hdl(key, seqNum); 00248 00249 for (MsgHandleBuf::iterator it = mhBufBegin; it != mhBufEnd; ++it) { 00250 if (it->key.isUnspecified()) { 00251 continue; 00252 } 00253 00254 if (*it == hdl) { 00255 return true; 00256 } 00257 } 00258 00259 *(mhBufNext++) = hdl; 00260 if (mhBufNext == mhBufEnd) { 00261 mhBufNext = mhBufBegin; 00262 } 00263 return false; 00264 }
void KBRTestApp::evaluateData | ( | simtime_t | timeDelay, | |
int | hopCount, | |||
long int | bytes | |||
) | [private] |
Analyses and records measuring data handed over from nodes that previously had been the destination for a test message from this module, called by receiver::handleMessage() at sendermodule.
timeDelay | packet-delay | |
hopCount | packet hop-count | |
bytes | packet size in bytes |
00267 { 00268 // count the number and size of successfully delivered messages 00269 RECORD_STATS(numDelivered++; bytesDelivered += bytes; 00270 globalStatistics->deliveredKBRTestAppMessages++); 00271 00272 if (numOverlaySent < numDelivered) { 00273 error("KBRTestApp::evaluateData(): numSent < numDelivered!"); 00274 } 00275 00276 RECORD_STATS(globalStatistics->recordOutVector("KBRTestApp: KBR Hop " 00277 "Count", hopCount)); 00278 RECORD_STATS(globalStatistics->recordOutVector("KBRTestApp: KBR Latency", 00279 latency)); 00280 }
void KBRTestApp::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [private, virtual] |
This method is called if an RPC response has been received.
msg | The response message. | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
rtt | The Round-Trip-Time of this RPC |
Reimplemented from RpcListener.
00149 { 00150 RPC_SWITCH_START(msg) 00151 RPC_ON_RESPONSE(Lookup) { 00152 handleLookupResponse(_LookupResponse); 00153 EV << "[KBRTestApp::handleRpcResponse() @ " << overlay->getThisNode().ip 00154 << " (" << overlay->getThisNode().key.toString(16) << ")]\n" 00155 << " Lookup RPC Response received: id=" << rpcId << "\n" 00156 << " msg=" << *_LookupResponse << " rtt=" << rtt 00157 << endl; 00158 break; 00159 } 00160 RPC_SWITCH_END( ) 00161 }
void KBRTestApp::handleLookupResponse | ( | LookupResponse * | msg | ) | [private] |
Referenced by handleRpcResponse().
00164 { 00165 EV << "[KBRTestApp::handleLookupResponse() @ " << overlay->getThisNode().ip 00166 << " (" << overlay->getThisNode().key.toString(16) << ")]\n" 00167 << " Lookup response for key " << msg->getKey()<< " : "; 00168 if (msg->getIsValid()) { 00169 for (uint i=0; i<msg->getSiblingsArraySize(); i++) { 00170 EV << endl << " " << msg->getSiblings(i); 00171 } 00172 } else { 00173 EV << "failed"; 00174 } 00175 00176 EV << endl; 00177 }
void KBRTestApp::pingResponse | ( | PingResponse * | response, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [private, virtual] |
void KBRTestApp::handleNodeLeaveNotification | ( | ) | [private, virtual] |
This method gets call **.gracefulLeaveDelay seconds before it is killed.
Reimplemented from BaseApp.
00180 { 00181 nodeIsLeavingSoon = true; 00182 }
double KBRTestApp::mean [private] |
mean time interval between sending test messages
Referenced by handleTimerEvent(), and initializeApp().
double KBRTestApp::deviation [private] |
bool KBRTestApp::activeNetwInitPhase [private] |
bool KBRTestApp::lookupNodeIds [private] |
bool KBRTestApp::nodeIsLeavingSoon [private] |
true if the node is going to be killed shortly
Referenced by handleNodeLeaveNotification(), handleTimerEvent(), and initializeApp().
int KBRTestApp::numDelivered [private] |
int KBRTestApp::bytesDelivered [private] |
int KBRTestApp::numDropped [private] |
Referenced by deliver(), finishApp(), and initializeApp().
int KBRTestApp::bytesDropped [private] |
Referenced by deliver(), finishApp(), and initializeApp().
cMessage* KBRTestApp::testTimer [private] |
Referenced by handleTimerEvent(), initializeApp(), KBRTestApp(), and ~KBRTestApp().
uint KBRTestApp::sequenceNumber [private] |
Referenced by handleTimerEvent(), and initializeApp().
int KBRTestApp::msgHandleBufSize [private] |
MsgHandleBuf KBRTestApp::mhBuf [private] |
MsgHandleBuf::iterator KBRTestApp::mhBufBegin [private] |
MsgHandleBuf::iterator KBRTestApp::mhBufNext [private] |
MsgHandleBuf::iterator KBRTestApp::mhBufEnd [private] |