MessageObserver.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00022 #include <assert.h>
00023 #include <sstream>
00024 #include <omnetpp.h>
00025 #include "MessageObserver.h"
00026 #include "ALMTestTracedMessage_m.h"
00027
00028 Define_Module(MessageObserver);
00029
00030 MessageObserver::MessageObserver() {
00031 gcTimer = new cMessage("garbage_collection");
00032 gcInterval = 1.0;
00033 cacheMaxAge = 10.0;
00034 }
00035
00036 MessageObserver::~MessageObserver() {
00037 cancelAndDelete(gcTimer);
00038 }
00039
00040 void MessageObserver::initialize() {
00041 WATCH_MAP(groups);
00042 WATCH_MAP(joinedAt);
00043 WATCH_MAP(receivedAt);
00044
00045 gcInterval = par("gcInterval");
00046 cacheMaxAge = par("cacheMaxAge");
00047
00048 if (gcInterval > 0.0)
00049 scheduleAt(OPP::simTime() + gcInterval, gcTimer);
00050 }
00051
00052 void MessageObserver::finish() {
00053 uint64_t totalSent = 0;
00054 uint64_t totalReceived = 0;
00055 for (std::map<OverlayKey, MulticastGroup>::iterator i = groups.begin(); i != groups.end(); ++i) {
00056 std::stringstream message;
00057 message << "MessageObserver: Group " << i->first;
00058 std::string name;
00059
00060 name = message.str() + " Sent Messages";
00061 recordScalar(name.c_str(), (double)i->second.sent);
00062
00063 name = message.str() + " Received Messages";
00064 recordScalar(name.c_str(), (double)i->second.received);
00065
00066 name = message.str() + " Delivered Percentage";
00067 recordScalar(name.c_str(), ((double)i->second.received * 100.0) / (double)i->second.sent);
00068
00069 totalSent += i->second.sent;
00070 totalReceived += i->second.received;
00071 }
00072
00073 recordScalar("MessageObserver: Total Sent Messages", (double)totalSent);
00074 recordScalar("MessageObserver: Total Received Messages", (double)totalReceived);
00075 recordScalar("MessageObserver: Total Delivered Percentage", ((double)totalReceived * 100.0) / (double)totalSent);
00076 }
00077
00078 void MessageObserver::handleMessage(cMessage* msg) {
00079 if (msg == gcTimer) {
00080 simtime_t now = OPP::simTime();
00081 std::map<NodeMessagePair, simtime_t>::iterator i, iPrev;
00082 i = receivedAt.begin();
00083 while (i != receivedAt.end()) {
00084 if (now - i->second >= cacheMaxAge) {
00085 iPrev = i;
00086 ++i;
00087 receivedAt.erase(iPrev);
00088 }
00089 else {
00090 ++i;
00091 }
00092 }
00093 scheduleAt(OPP::simTime() + gcInterval, gcTimer);
00094 }
00095 }
00096
00100 void MessageObserver::joinedGroup(int moduleId, OverlayKey groupId) {
00101 groups[groupId].size += 1;
00102 joinedAt[NodeGroupPair(moduleId, groupId)] = OPP::simTime();
00103 }
00104
00108 void MessageObserver::leftGroup(int moduleId, OverlayKey groupId) {
00109 std::map<OverlayKey, MulticastGroup>::iterator iter = groups.find(groupId);
00110 if (iter == groups.end()) {
00111 EV << "Warning: MessageObserver asked to remove node from nonexistent group " << groupId.toString();
00112 }
00113 else if (iter->second.size == 0) {
00114 EV << "Warning: MessageObserver asked to remove node from empty group " << groupId.toString();
00115 }
00116 else {
00117 iter->second.size -= 1;
00118 }
00119 joinedAt.erase(NodeGroupPair(moduleId, groupId));
00120 }
00121
00126 void MessageObserver::sentMessage(ALMTestTracedMessage* msg) {
00127 if (msg == NULL) {
00128 error("%s called with null message.", __PRETTY_FUNCTION__);
00129 }
00130
00131 std::map<OverlayKey, MulticastGroup>::iterator iter;
00132 iter = groups.find(msg->getGroupId());
00133 if (iter == groups.end()) {
00134 EV << "Warning: MessageObserver notified of sent message for nonexistent group " << msg->getGroupId().toString();
00135 }
00136 else if (iter->second.size == 0) {
00137 EV << "Warning: MessageObserver notified of sent message for empty group " << msg->getGroupId().toString();
00138 }
00139 else {
00140 iter->second.sent += iter->second.size - 1;
00141 }
00142 }
00143
00147 void MessageObserver::receivedMessage(ALMTestTracedMessage* msg) {
00148 if (msg == NULL) {
00149 error("%s called with null message.", __PRETTY_FUNCTION__);
00150 }
00151
00152 std::map<OverlayKey, MulticastGroup>::iterator iGroup;
00153 iGroup = groups.find(msg->getGroupId());
00154 if (iGroup == groups.end()) {
00155 EV << "Warning: MessageObserver notified of received message for nonexistent group " << msg->getGroupId().toString();
00156 }
00157 else if (iGroup->second.size == 0) {
00158 EV << "Warning: MessageObserver notified of received message for empty group " << msg->getGroupId().toString();
00159 }
00160 else if (msg->getSenderId() != msg->getReceiverId()) {
00161
00162
00163 std::map<NodeGroupPair, simtime_t>::iterator iJoinInfo;
00164 iJoinInfo = joinedAt.find(NodeGroupPair(msg->getReceiverId(), msg->getGroupId()));
00165
00166 if (iJoinInfo != joinedAt.end() && iJoinInfo->second < msg->getTimestamp()) {
00167
00168
00169 NodeMessagePair nmp = NodeMessagePair(msg->getReceiverId(), msg->getMcastId());
00170 if (receivedAt.find(nmp) == receivedAt.end()) {
00171 iGroup->second.received += 1;
00172 receivedAt[nmp] = msg->getTimestamp();
00173 }
00174 }
00175 }
00176 else {
00177
00178 }
00179 }
00180
00181 std::ostream& operator<< (std::ostream& os, MessageObserver::MulticastGroup const & mg) {
00182 return os << "Nodes: " << mg.size << "; Messages Sent: " << mg.sent
00183 << ", Received: " << mg.received << ", Dropped: " << (mg.sent - mg.received);
00184 }
00185
00186 std::ostream& operator<< (std::ostream& os, MessageObserver::NodeGroupPair const & ngp) {
00187 cModule* module = OPP::cSimulation::getActiveSimulation()->getModule(ngp.first);
00188 return os << "(" << (module != NULL ? module->getFullPath() : "Deleted node")
00189 << ", " << ngp.second << ")";
00190 }
00191