A simple test application for the DHT layer. More...
#include <DHTTestApp.h>
Classes | |
class | DHTStatsContext |
A container used by the DHTTestApp to store context information for statistics. More... | |
Public Member Functions | |
DHTTestApp () | |
virtual | ~DHTTestApp () |
virtual destructor | |
Private Member Functions | |
void | initializeApp (int stage) |
initializes derived class-attributes | |
OverlayKey | getRandomKey () |
Get a random key of the hashmap. | |
BinaryValue | generateRandomValue () |
generate a random human readable binary value | |
void | finishApp () |
collects statistical data of derived app | |
virtual void | handleGetResponse (DHTgetCAPIResponse *msg, DHTStatsContext *context) |
processes get responses | |
virtual void | handlePutResponse (DHTputCAPIResponse *msg, DHTStatsContext *context) |
processes put responses | |
virtual void | handleTimerEvent (cMessage *msg) |
processes self-messages | |
virtual void | handleTraceMessage (cMessage *msg) |
handleTraceMessage gets called of handleMessage(cMessage* msg) if a message arrives at trace_in. | |
virtual void | handleNodeLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed. | |
void | handleRpcResponse (BaseResponseMessage *msg, const RpcState &state, simtime_t rtt) |
Private Attributes | |
UnderlayConfigurator * | underlayConfigurator |
pointer to UnderlayConfigurator in this node | |
GlobalNodeList * | globalNodeList |
pointer to GlobalNodeList in this node | |
GlobalStatistics * | globalStatistics |
pointer to GlobalStatistics module in this node | |
GlobalDhtTestMap * | globalDhtTestMap |
pointer to the GlobalDhtTestMap module | |
bool | debugOutput |
debug output yes/no? | |
double | mean |
mean time interval between sending test messages | |
double | deviation |
deviation of time interval | |
int | ttl |
ttl for stored DHT records | |
bool | p2pnsTraffic |
model p2pns application traffic */ | |
bool | activeNetwInitPhase |
is app active in network init phase? | |
int | numSent |
number of sent packets | |
int | numGetSent |
number of get sent | |
int | numGetError |
number of false get responses | |
int | numGetSuccess |
number of false get responses | |
int | numPutSent |
number of put sent | |
int | numPutError |
number of error in put responses | |
int | numPutSuccess |
number of success in put responses | |
cMessage * | dhttestput_timer |
cMessage * | dhttestget_timer |
cMessage * | dhttestmod_timer |
bool | nodeIsLeavingSoon |
true if the node is going to be killed shortly | |
Static Private Attributes | |
static const int | DHTTESTAPP_VALUE_LEN = 20 |
A simple test application for the DHT layer.
A simple test application that does random put and get calls on the DHT layer
Definition at line 50 of file DHTTestApp.h.
DHTTestApp::DHTTestApp | ( | ) |
Definition at line 46 of file DHTTestApp.cc.
{ dhttestput_timer = NULL; dhttestget_timer = NULL; dhttestmod_timer = NULL; }
DHTTestApp::~DHTTestApp | ( | ) | [virtual] |
virtual destructor
Definition at line 39 of file DHTTestApp.cc.
{ cancelAndDelete(dhttestput_timer); cancelAndDelete(dhttestget_timer); cancelAndDelete(dhttestmod_timer); }
void DHTTestApp::finishApp | ( | ) | [private, virtual] |
collects statistical data of derived app
Reimplemented from BaseApp.
Definition at line 436 of file DHTTestApp.cc.
{ simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); if (time >= GlobalStatistics::MIN_MEASURED) { // record scalar data globalStatistics->addStdDev("DHTTestApp: Sent Total Messages/s", numSent / time); globalStatistics->addStdDev("DHTTestApp: Sent GET Messages/s", numGetSent / time); globalStatistics->addStdDev("DHTTestApp: Failed GET Requests/s", numGetError / time); globalStatistics->addStdDev("DHTTestApp: Successful GET Requests/s", numGetSuccess / time); globalStatistics->addStdDev("DHTTestApp: Sent PUT Messages/s", numPutSent / time); globalStatistics->addStdDev("DHTTestApp: Failed PUT Requests/s", numPutError / time); globalStatistics->addStdDev("DHTTestApp: Successful PUT Requests/s", numPutSuccess / time); if ((numGetSuccess + numGetError) > 0) { globalStatistics->addStdDev("DHTTestApp: GET Success Ratio", (double) numGetSuccess / (double) (numGetSuccess + numGetError)); } } }
BinaryValue DHTTestApp::generateRandomValue | ( | ) | [private] |
generate a random human readable binary value
Definition at line 419 of file DHTTestApp.cc.
Referenced by handleTimerEvent().
{ char value[DHTTESTAPP_VALUE_LEN + 1]; for (int i = 0; i < DHTTESTAPP_VALUE_LEN; i++) { value[i] = intuniform(0, 25) + 'a'; } value[DHTTESTAPP_VALUE_LEN] = '\0'; return BinaryValue(value); }
OverlayKey DHTTestApp::getRandomKey | ( | ) | [private] |
Get a random key of the hashmap.
void DHTTestApp::handleGetResponse | ( | DHTgetCAPIResponse * | msg, | |
DHTStatsContext * | context | |||
) | [private, virtual] |
processes get responses
method to handle get responses should be overwritten in derived application if needed
msg | get response message | |
context | context object used for collecting statistics |
Definition at line 172 of file DHTTestApp.cc.
Referenced by handleRpcResponse().
{ if (context->measurementPhase == false) { // don't count response, if the request was not sent // in the measurement phase delete context; return; } RECORD_STATS(globalStatistics->addStdDev("DHTTestApp: GET Latency (s)", SIMTIME_DBL(simTime() - context->requestTime))); if (!(msg->getIsSuccess())) { //cout << "DHTTestApp: success == false" << endl; RECORD_STATS(numGetError++); delete context; return; } const DHTEntry* entry = globalDhtTestMap->findEntry(context->key); if (entry == NULL) { //unexpected key RECORD_STATS(numGetError++); //cout << "DHTTestApp: unexpected key" << endl; delete context; return; } if (simTime() > entry->endtime) { //this key doesn't exist anymore in the DHT, delete it in our hashtable globalDhtTestMap->eraseEntry(context->key); delete context; if (msg->getResultArraySize() > 0) { RECORD_STATS(numGetError++); //cout << "DHTTestApp: deleted key still available" << endl; return; } else { RECORD_STATS(numGetSuccess++); //cout << "DHTTestApp: success (1)" << endl; return; } } else { delete context; if ((msg->getResultArraySize() > 0) && (msg->getResult(0).getValue() != entry->value)) { RECORD_STATS(numGetError++); //cout << "DHTTestApp: wrong value" << endl; //cout << "value: " << msg->getResult(0).getValue() << endl; return; } else { RECORD_STATS(numGetSuccess++); //cout << "DHTTestApp: success (2)" << endl; return; } } }
void DHTTestApp::handleNodeLeaveNotification | ( | ) | [private, virtual] |
This method gets call **.gracefulLeaveDelay seconds before it is killed.
Reimplemented from BaseApp.
Definition at line 431 of file DHTTestApp.cc.
{ nodeIsLeavingSoon = true; }
void DHTTestApp::handlePutResponse | ( | DHTputCAPIResponse * | msg, | |
DHTStatsContext * | context | |||
) | [private, virtual] |
processes put responses
method to handle put responses should be overwritten in derived application if needed
msg | put response message | |
context | context object used for collecting statistics |
Definition at line 147 of file DHTTestApp.cc.
Referenced by handleRpcResponse().
{ DHTEntry entry = {context->value, simTime() + ttl}; globalDhtTestMap->insertEntry(context->key, entry); if (context->measurementPhase == false) { // don't count response, if the request was not sent // in the measurement phase delete context; return; } if (msg->getIsSuccess()) { RECORD_STATS(numPutSuccess++); RECORD_STATS(globalStatistics->addStdDev("DHTTestApp: PUT Latency (s)", SIMTIME_DBL(simTime() - context->requestTime))); } else { RECORD_STATS(numPutError++); } delete context; }
void DHTTestApp::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
const RpcState & | state, | |||
simtime_t | rtt | |||
) | [private] |
Definition at line 121 of file DHTTestApp.cc.
{ RPC_SWITCH_START(msg) RPC_ON_RESPONSE( DHTputCAPI ) { handlePutResponse(_DHTputCAPIResponse, check_and_cast<DHTStatsContext*>(state.getContext())); EV << "[DHTTestApp::handleRpcResponse()]\n" << " DHT Put RPC Response received: id=" << state.getId() << " msg=" << *_DHTputCAPIResponse << " rtt=" << rtt << endl; break; } RPC_ON_RESPONSE(DHTgetCAPI) { handleGetResponse(_DHTgetCAPIResponse, check_and_cast<DHTStatsContext*>(state.getContext())); EV << "[DHTTestApp::handleRpcResponse()]\n" << " DHT Get RPC Response received: id=" << state.getId() << " msg=" << *_DHTgetCAPIResponse << " rtt=" << rtt << endl; break; } RPC_SWITCH_END() }
void DHTTestApp::handleTimerEvent | ( | cMessage * | msg | ) | [private, virtual] |
processes self-messages
method to handle self-messages should be overwritten in derived application if needed
msg | self-message |
Definition at line 291 of file DHTTestApp.cc.
{ if (msg->isName("dhttest_put_timer")) { // schedule next timer event scheduleAt(simTime() + truncnormal(mean, deviation), msg); // do nothing if the network is still in the initialization phase if (((!activeNetwInitPhase) && (underlayConfigurator->isInInitPhase())) || underlayConfigurator->isSimulationEndingSoon() || nodeIsLeavingSoon) return; if (p2pnsTraffic) { if (globalDhtTestMap->p2pnsNameCount < 4*globalNodeList->getNumNodes()) { for (int i = 0; i < 4; i++) { // create a put test message with random destination key OverlayKey destKey = OverlayKey::random(); DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); dhtPutMsg->setKey(destKey); dhtPutMsg->setValue(generateRandomValue()); dhtPutMsg->setTtl(ttl); dhtPutMsg->setIsModifiable(true); RECORD_STATS(numSent++; numPutSent++); sendInternalRpcCall(TIER1_COMP, dhtPutMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), destKey, dhtPutMsg->getValue())); globalDhtTestMap->p2pnsNameCount++; } } cancelEvent(msg); return; } // create a put test message with random destination key OverlayKey destKey = OverlayKey::random(); DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); dhtPutMsg->setKey(destKey); dhtPutMsg->setValue(generateRandomValue()); dhtPutMsg->setTtl(ttl); dhtPutMsg->setIsModifiable(true); RECORD_STATS(numSent++; numPutSent++); sendInternalRpcCall(TIER1_COMP, dhtPutMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), destKey, dhtPutMsg->getValue())); } else if (msg->isName("dhttest_get_timer")) { scheduleAt(simTime() + truncnormal(mean, deviation), msg); // do nothing if the network is still in the initialization phase if (((!activeNetwInitPhase) && (underlayConfigurator->isInInitPhase())) || underlayConfigurator->isSimulationEndingSoon() || nodeIsLeavingSoon) { return; } if (p2pnsTraffic && (uniform(0, 1) > ((double)mean/1800.0))) { return; } const OverlayKey& key = globalDhtTestMap->getRandomKey(); if (key.isUnspecified()) { EV << "[DHTTestApp::handleTimerEvent() @ " << thisNode.getIp() << " (" << thisNode.getKey().toString(16) << ")]\n" << " Error: No key available in global DHT test map!" << endl; return; } DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall(); dhtGetMsg->setKey(key); RECORD_STATS(numSent++; numGetSent++); sendInternalRpcCall(TIER1_COMP, dhtGetMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), key)); } else if (msg->isName("dhttest_mod_timer")) { scheduleAt(simTime() + truncnormal(mean, deviation), msg); // do nothing if the network is still in the initialization phase if (((!activeNetwInitPhase) && (underlayConfigurator->isInInitPhase())) || underlayConfigurator->isSimulationEndingSoon() || nodeIsLeavingSoon) { return; } if (p2pnsTraffic) { if (globalDhtTestMap->p2pnsNameCount >= 4*globalNodeList->getNumNodes()) { const OverlayKey& key = globalDhtTestMap->getRandomKey(); if (key.isUnspecified()) return; DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); dhtPutMsg->setKey(key); dhtPutMsg->setValue(generateRandomValue()); dhtPutMsg->setTtl(ttl); dhtPutMsg->setIsModifiable(true); RECORD_STATS(numSent++; numPutSent++); sendInternalRpcCall(TIER1_COMP, dhtPutMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), key, dhtPutMsg->getValue())); } cancelEvent(msg); return; } const OverlayKey& key = globalDhtTestMap->getRandomKey(); if (key.isUnspecified()) return; DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); dhtPutMsg->setKey(key); dhtPutMsg->setValue(generateRandomValue()); dhtPutMsg->setTtl(ttl); dhtPutMsg->setIsModifiable(true); RECORD_STATS(numSent++; numPutSent++); sendInternalRpcCall(TIER1_COMP, dhtPutMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), key, dhtPutMsg->getValue())); } }
void DHTTestApp::handleTraceMessage | ( | cMessage * | msg | ) | [private, virtual] |
handleTraceMessage gets called of handleMessage(cMessage* msg) if a message arrives at trace_in.
The command included in this message should be parsed and handled.
msg | the command message to handle |
Reimplemented from BaseApp.
Definition at line 233 of file DHTTestApp.cc.
{ char* cmd = new char[strlen(msg->getName()) + 1]; strcpy(cmd, msg->getName()); if (strlen(msg->getName()) < 5) { delete[] cmd; delete msg; return; } if (strncmp(cmd, "PUT ", 4) == 0) { // Generate key char* buf = cmd + 4; while (!isspace(buf[0])) { if (buf[0] == '\0') throw cRuntimeError("Error parsing PUT command"); buf++; } buf[0] = '\0'; BinaryValue b(cmd + 4); OverlayKey destKey(OverlayKey::sha1(b)); // get value buf++; // build putMsg DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); dhtPutMsg->setKey(destKey); dhtPutMsg->setValue(buf); dhtPutMsg->setTtl(ttl); dhtPutMsg->setIsModifiable(true); RECORD_STATS(numSent++; numPutSent++); sendInternalRpcCall(TIER1_COMP, dhtPutMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), destKey)); } else if (strncmp(cmd, "GET ", 4) == 0) { // Get key BinaryValue b(cmd + 4); OverlayKey key(OverlayKey::sha1(b)); DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall(); dhtGetMsg->setKey(key); RECORD_STATS(numSent++; numGetSent++); sendInternalRpcCall(TIER1_COMP, dhtGetMsg, new DHTStatsContext(globalStatistics->isMeasuring(), simTime(), key)); } else { throw cRuntimeError("Unknown trace command; " "only GET and PUT are allowed"); } delete[] cmd; delete msg; }
void DHTTestApp::initializeApp | ( | int | stage | ) | [private, virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented from BaseApp.
Definition at line 53 of file DHTTestApp.cc.
{ if (stage != MIN_STAGE_APP) return; // fetch parameters debugOutput = par("debugOutput"); activeNetwInitPhase = par("activeNetwInitPhase"); mean = par("testInterval"); p2pnsTraffic = par("p2pnsTraffic"); deviation = mean / 10; if (p2pnsTraffic) { ttl = 3600*24*365; } else { ttl = par("testTtl"); } globalNodeList = GlobalNodeListAccess().get(); underlayConfigurator = UnderlayConfiguratorAccess().get(); globalStatistics = GlobalStatisticsAccess().get(); globalDhtTestMap = dynamic_cast<GlobalDhtTestMap*>(simulation.getModuleByPath( "globalObserver.globalFunctions[0].function")); if (globalDhtTestMap == NULL) { throw cRuntimeError("DHTTestApp::initializeApp(): " "GlobalDhtTestMap module not found!"); } // statistics numSent = 0; numGetSent = 0; numGetError = 0; numGetSuccess = 0; numPutSent = 0; numPutError = 0; numPutSuccess = 0; //initRpcs(); WATCH(numSent); WATCH(numGetSent); WATCH(numGetError); WATCH(numGetSuccess); WATCH(numPutSent); WATCH(numPutError); WATCH(numPutSuccess); nodeIsLeavingSoon = false; // initiate test message transmission dhttestput_timer = new cMessage("dhttest_put_timer"); dhttestget_timer = new cMessage("dhttest_get_timer"); dhttestmod_timer = new cMessage("dhttest_mod_timer"); if (mean > 0) { scheduleAt(simTime() + truncnormal(mean, deviation), dhttestput_timer); scheduleAt(simTime() + truncnormal(mean + mean / 3, deviation), dhttestget_timer); scheduleAt(simTime() + truncnormal(mean + 2 * mean / 3, deviation), dhttestmod_timer); } }
bool DHTTestApp::activeNetwInitPhase [private] |
is app active in network init phase?
Definition at line 148 of file DHTTestApp.h.
Referenced by handleTimerEvent(), and initializeApp().
bool DHTTestApp::debugOutput [private] |
debug output yes/no?
Reimplemented from BaseApp.
Definition at line 143 of file DHTTestApp.h.
Referenced by initializeApp().
double DHTTestApp::deviation [private] |
deviation of time interval
Definition at line 145 of file DHTTestApp.h.
Referenced by handleTimerEvent(), and initializeApp().
const int DHTTestApp::DHTTESTAPP_VALUE_LEN = 20 [static, private] |
Definition at line 162 of file DHTTestApp.h.
Referenced by generateRandomValue().
cMessage * DHTTestApp::dhttestget_timer [private] |
Definition at line 159 of file DHTTestApp.h.
Referenced by DHTTestApp(), initializeApp(), and ~DHTTestApp().
cMessage * DHTTestApp::dhttestmod_timer [private] |
Definition at line 159 of file DHTTestApp.h.
Referenced by DHTTestApp(), initializeApp(), and ~DHTTestApp().
cMessage* DHTTestApp::dhttestput_timer [private] |
Definition at line 159 of file DHTTestApp.h.
Referenced by DHTTestApp(), initializeApp(), and ~DHTTestApp().
GlobalDhtTestMap* DHTTestApp::globalDhtTestMap [private] |
pointer to the GlobalDhtTestMap module
Definition at line 140 of file DHTTestApp.h.
Referenced by handleGetResponse(), handlePutResponse(), handleTimerEvent(), and initializeApp().
GlobalNodeList* DHTTestApp::globalNodeList [private] |
pointer to GlobalNodeList in this node
Reimplemented from BaseApp.
Definition at line 137 of file DHTTestApp.h.
Referenced by handleTimerEvent(), and initializeApp().
GlobalStatistics* DHTTestApp::globalStatistics [private] |
pointer to GlobalStatistics module in this node
Reimplemented from BaseApp.
Definition at line 139 of file DHTTestApp.h.
Referenced by finishApp(), handleGetResponse(), handlePutResponse(), handleTimerEvent(), handleTraceMessage(), and initializeApp().
double DHTTestApp::mean [private] |
mean time interval between sending test messages
Definition at line 144 of file DHTTestApp.h.
Referenced by handleTimerEvent(), and initializeApp().
bool DHTTestApp::nodeIsLeavingSoon [private] |
true if the node is going to be killed shortly
Definition at line 160 of file DHTTestApp.h.
Referenced by handleNodeLeaveNotification(), handleTimerEvent(), and initializeApp().
int DHTTestApp::numGetError [private] |
number of false get responses
Definition at line 153 of file DHTTestApp.h.
Referenced by finishApp(), handleGetResponse(), and initializeApp().
int DHTTestApp::numGetSent [private] |
number of get sent
Definition at line 152 of file DHTTestApp.h.
Referenced by finishApp(), handleTimerEvent(), handleTraceMessage(), and initializeApp().
int DHTTestApp::numGetSuccess [private] |
number of false get responses
Definition at line 154 of file DHTTestApp.h.
Referenced by finishApp(), handleGetResponse(), and initializeApp().
int DHTTestApp::numPutError [private] |
number of error in put responses
Definition at line 156 of file DHTTestApp.h.
Referenced by finishApp(), handlePutResponse(), and initializeApp().
int DHTTestApp::numPutSent [private] |
number of put sent
Definition at line 155 of file DHTTestApp.h.
Referenced by finishApp(), handleTimerEvent(), handleTraceMessage(), and initializeApp().
int DHTTestApp::numPutSuccess [private] |
number of success in put responses
Definition at line 157 of file DHTTestApp.h.
Referenced by finishApp(), handlePutResponse(), and initializeApp().
int DHTTestApp::numSent [private] |
number of sent packets
Definition at line 151 of file DHTTestApp.h.
Referenced by finishApp(), handleTimerEvent(), handleTraceMessage(), and initializeApp().
bool DHTTestApp::p2pnsTraffic [private] |
model p2pns application traffic */
Definition at line 147 of file DHTTestApp.h.
Referenced by handleTimerEvent(), and initializeApp().
int DHTTestApp::ttl [private] |
ttl for stored DHT records
Definition at line 146 of file DHTTestApp.h.
Referenced by handlePutResponse(), handleTimerEvent(), handleTraceMessage(), and initializeApp().
pointer to UnderlayConfigurator in this node
Reimplemented from BaseApp.
Definition at line 135 of file DHTTestApp.h.
Referenced by handleTimerEvent(), and initializeApp().