00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <assert.h>
00025
00026 #include <BaseApp.h>
00027 #include "Scribe.h"
00028 #include <GlobalStatistics.h>
00029
00030 #include "Comparator.h"
00031
00032 Define_Module(Scribe);
00033
00034 using namespace std;
00035
00036 Scribe::Scribe()
00037 {
00038 subscriptionTimer = new ScribeTimer("Subscription timer");
00039 subscriptionTimer->setTimerType( SCRIBE_SUBSCRIPTION_REFRESH );
00040 numJoins = 0;
00041 numChildTimeout = 0;
00042 numParentTimeout = 0;
00043 numForward = 0;
00044 forwardBytes = 0;
00045 numReceived = 0;
00046 receivedBytes = 0;
00047 numHeartbeat = 0;
00048 heartbeatBytes = 0;
00049 numSubscriptionRefresh = 0;
00050 subscriptionRefreshBytes = 0;
00051 }
00052
00053 Scribe::~Scribe()
00054 {
00055 groupList.clear();
00056 cancelAndDelete(subscriptionTimer);
00057
00058 }
00059
00060 void Scribe::initializeApp(int stage)
00061 {
00062 if( stage != (numInitStages()-1))
00063 {
00064 return;
00065 }
00066 WATCH(groupList);
00067 WATCH(numJoins);
00068 WATCH(numForward);
00069 WATCH(forwardBytes);
00070 WATCH(numReceived);
00071 WATCH(receivedBytes);
00072 WATCH(numHeartbeat);
00073 WATCH(heartbeatBytes);
00074 WATCH(numSubscriptionRefresh);
00075 WATCH(subscriptionRefreshBytes);
00076 WATCH(numChildTimeout);
00077 WATCH(numParentTimeout);
00078
00079 childTimeout = par("childTimeout");
00080 parentTimeout = par("parentTimeout");
00081
00082 }
00083
00084 void Scribe::finishApp()
00085 {
00086 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00087 if (time < GlobalStatistics::MIN_MEASURED) return;
00088
00089 globalStatistics->addStdDev("Scribe: Received JOIN Messages/s",
00090 numJoins / time);
00091 globalStatistics->addStdDev("Scribe: Forwarded Multicast Messages/s",
00092 numForward / time);
00093 globalStatistics->addStdDev("Scribe: Forwarded Multicast Bytes/s",
00094 forwardBytes / time);
00095 globalStatistics->addStdDev("Scribe: Received Multicast Messages/s (subscribed groups only)",
00096 numReceived / time);
00097 globalStatistics->addStdDev("Scribe: Received Multicast Bytes/s (subscribed groups only)",
00098 receivedBytes / time);
00099 globalStatistics->addStdDev("Scribe: Send Heartbeat Messages/s",
00100 numHeartbeat / time);
00101 globalStatistics->addStdDev("Scribe: Send Heartbeat Bytes/s",
00102 heartbeatBytes / time);
00103 globalStatistics->addStdDev("Scribe: Send Subscription Refresh Messages/s",
00104 numSubscriptionRefresh / time);
00105 globalStatistics->addStdDev("Scribe: Send Subscription Refresh Bytes/s",
00106 subscriptionRefreshBytes / time);
00107 globalStatistics->addStdDev("Scribe: Number of Child Timeouts/s",
00108 numChildTimeout / time);
00109 globalStatistics->addStdDev("Scribe: Number of Parent Timeouts/s",
00110 numParentTimeout / time);
00111 }
00112
00113 void Scribe::forward(OverlayKey* key, cPacket** msg,
00114 NodeHandle* nextHopNode)
00115 {
00116 ScribeJoinCall* joinMsg = dynamic_cast<ScribeJoinCall*> (*msg);
00117 if( joinMsg == NULL ) {
00118
00119 return;
00120 }
00121
00122 if( joinMsg->getSrcNode() == overlay->getThisNode() ) return;
00123
00124 handleJoinMessage( joinMsg, false );
00125
00126 *msg = NULL;
00127 }
00128
00129 void Scribe::update( const NodeHandle& node, bool joined )
00130 {
00131
00132 for( GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it ){
00133
00134 if( !it->second.getParent().isUnspecified()
00135 && it->second.getParent() == overlay->getThisNode() ) {
00136 KeyDistanceComparator<KeyRingMetric> comp( it->second.getGroupId() );
00137
00138 if( comp.compare(node.getKey(), overlay->getThisNode().getKey()) < 0){
00139
00140 ScribeJoinCall* m = new ScribeJoinCall;
00141 m->setGroupId( it->second.getGroupId() );
00142 m->setBitLength( SCRIBE_JOINCALL_L(m) );
00143 sendRouteRpcCall(TIER1_COMP, node, m);
00144 }
00145 }
00146 }
00147 }
00148
00149 bool Scribe::handleRpcCall(BaseCallMessage* msg)
00150 {
00151 RPC_SWITCH_START(msg);
00152 RPC_DELEGATE(ScribeJoin, handleJoinCall);
00153 RPC_DELEGATE(ScribePublish, handlePublishCall);
00154 RPC_SWITCH_END();
00155 return RPC_HANDLED;
00156 }
00157
00158 void Scribe::handleRpcResponse(BaseResponseMessage* msg,
00159 cPolymorphic* context, int rpcId,
00160 simtime_t rtt)
00161 {
00162 RPC_SWITCH_START(msg);
00163 RPC_ON_RESPONSE( ScribeJoin ) {
00164 handleJoinResponse( _ScribeJoinResponse );
00165 EV << "[Scribe::handleRpcResponse() @ " << overlay->getThisNode().getAddress()
00166 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00167 << " Received a ScribeJoin RPC Response: id=" << rpcId << "\n"
00168 << " msg=" << *_ScribeJoinResponse << " rtt=" << rtt
00169 << endl;
00170 break;
00171 }
00172 RPC_ON_RESPONSE( ScribePublish ) {
00173 handlePublishResponse( _ScribePublishResponse );
00174 }
00175 RPC_SWITCH_END( );
00176 }
00177
00178 void Scribe::deliver(OverlayKey& key, cMessage* msg)
00179 {
00180 if( ScribeSubscriptionRefreshMessage* refreshMsg =
00181 dynamic_cast<ScribeSubscriptionRefreshMessage*>(msg) ){
00182
00183 refreshChildTimer( refreshMsg->getSrc(), refreshMsg->getGroupId() );
00184 delete refreshMsg;
00185 } else if( ScribeDataMessage* data = dynamic_cast<ScribeDataMessage*>(msg) ){
00186 deliverALMDataToGroup( data );
00187 } else if( ScribeLeaveMessage* leaveMsg = dynamic_cast<ScribeLeaveMessage*>(msg) ){
00188 handleLeaveMessage( leaveMsg );
00189 }
00190 }
00191
00192 void Scribe::handleUpperMessage( cMessage *msg )
00193 {
00194 if( ALMSubscribeMessage* subscribeMsg = dynamic_cast<ALMSubscribeMessage*>(msg)){
00195 subscribeToGroup( subscribeMsg->getGroupId() );
00196 delete msg;
00197 } else if( ALMLeaveMessage* leaveMsg = dynamic_cast<ALMLeaveMessage*>(msg)){
00198 leaveGroup( leaveMsg->getGroupId() );
00199 delete msg;
00200 } else if( ALMMulticastMessage* mcastMsg = dynamic_cast<ALMMulticastMessage*>(msg) ){
00201 deliverALMDataToRoot( mcastMsg );
00202 } else if( ALMAnycastMessage* acastMsg = dynamic_cast<ALMAnycastMessage*>(msg) ){
00203
00204 EV << "[Scribe::handleUpperMessage() @ " << overlay->getThisNode().getAddress()
00205 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00206 << " Anycast message for group " << acastMsg->getGroupId() << "\n"
00207 << " ignored: Not implemented yet!"
00208 << endl;
00209 delete msg;
00210 } else if( ALMCreateMessage* createMsg = dynamic_cast<ALMCreateMessage*>(msg) ){
00211 EV << "[Scribe::handleUpperMessage() @ " << overlay->getThisNode().getAddress()
00212 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00213 << " Create message for group " << createMsg->getGroupId() << "\n"
00214 << " ignored: Scribe has implicit create on SUBSCRIBE"
00215 << endl;
00216 delete msg;
00217 } else if( ALMDeleteMessage* deleteMsg = dynamic_cast<ALMDeleteMessage*>(msg) ){
00218 EV << "[Scribe::handleUpperMessage() @ " << overlay->getThisNode().getAddress()
00219 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00220 << " Delete message for group " << deleteMsg->getGroupId() << "\n"
00221 << " ignored: Scribe has implicit delete on LEAVE"
00222 << endl;
00223 delete msg;
00224 }
00225 }
00226
00227 void Scribe::handleReadyMessage( CompReadyMessage* msg )
00228 {
00229
00230 if( getThisCompType() - msg->getComp() == 1 ){
00231 if( !msg->getReady() ) {
00232 delete msg;
00233 return;
00234 }
00235
00236
00237 msg->setComp(getThisCompType());
00238 send( msg, "to_upperTier" );
00239 startTimer( subscriptionTimer );
00240 } else {
00241 delete msg;
00242 }
00243 }
00244
00245 void Scribe::handleTimerEvent( cMessage *msg )
00246 {
00247 ScribeTimer* timer = dynamic_cast<ScribeTimer*>(msg);
00248 assert( timer );
00249 switch( timer->getTimerType() ) {
00250 case SCRIBE_SUBSCRIPTION_REFRESH:
00251
00252 for( GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it ) {
00253 NodeHandle parent = it->second.getParent();
00254 if( !parent.isUnspecified() ){
00255 ScribeSubscriptionRefreshMessage* refreshMsg = new ScribeSubscriptionRefreshMessage;
00256 refreshMsg->setGroupId( it->second.getGroupId() );
00257 refreshMsg->setSrc( overlay->getThisNode() );
00258
00259 refreshMsg->setBitLength(SCRIBE_SUBSCRIPTIONREFRESH_L(refreshMsg));
00260 RECORD_STATS(++numSubscriptionRefresh;
00261 subscriptionRefreshBytes += refreshMsg->getByteLength()
00262 );
00263 callRoute( OverlayKey::UNSPECIFIED_KEY, refreshMsg, parent );
00264 }
00265 }
00266 startTimer( subscriptionTimer );
00267 break;
00268
00269 case SCRIBE_HEARTBEAT:
00270 {
00271
00272 GroupList::iterator groupIt = groupList.find( timer->getGroup() );
00273 if( groupIt == groupList.end() ) {
00274
00275 delete timer;
00276 return;
00277 }
00278 for( set<NodeHandle>::iterator it = groupIt->second.getChildrenBegin();
00279 it != groupIt->second.getChildrenEnd(); ++it ) {
00280 ScribeDataMessage* heartbeatMsg = new ScribeDataMessage("Heartbeat");
00281 heartbeatMsg->setEmpty( true );
00282 heartbeatMsg->setGroupId( timer->getGroup() );
00283
00284 heartbeatMsg->setBitLength(SCRIBE_DATA_L(heartbeatMsg));
00285 RECORD_STATS(++numHeartbeat; heartbeatBytes += heartbeatMsg->getByteLength());
00286 callRoute( OverlayKey::UNSPECIFIED_KEY, heartbeatMsg, *it );
00287 }
00288 startTimer( timer );
00289 break;
00290 }
00291 case SCRIBE_CHILD_TIMEOUT:
00292
00293 RECORD_STATS(++numChildTimeout);
00294 removeChildFromGroup( timer );
00295 break;
00296
00297 case SCRIBE_PARENT_TIMEOUT:
00298
00299 RECORD_STATS(++numParentTimeout);
00300 OverlayKey key = timer->getGroup();
00301 EV << "[Scribe::handleTimerEvent() @ " << overlay->getThisNode().getAddress()
00302 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00303 << " Parent of group " << key << "\n"
00304 << " failed to send heartbeat, trying to rejoin"
00305 << endl;
00306
00307 ScribeJoinCall* newJoin = new ScribeJoinCall;
00308 newJoin->setGroupId( key );
00309 newJoin->setBitLength( SCRIBE_JOINCALL_L(newJoin) );
00310 sendRouteRpcCall(TIER1_COMP, key, newJoin);
00311
00312 GroupList::iterator groupIt = groupList.find( timer->getGroup() );
00313 if( groupIt == groupList.end() ) {
00314
00315 delete timer;
00316 return;
00317 }
00318 groupIt->second.setParentTimer( NULL );
00319 cancelAndDelete( timer );
00320 break;
00321 }
00322
00323 }
00324
00325 void Scribe::handleJoinCall( ScribeJoinCall* joinMsg)
00326 {
00327 handleJoinMessage( joinMsg, true );
00328 }
00329
00330 void Scribe::handleJoinMessage( ScribeJoinCall* joinMsg, bool amIRoot)
00331 {
00332 RECORD_STATS(++numJoins);
00333 OverlayKey key = joinMsg->getGroupId();
00334
00335 EV << "[Scribe::handleJoinMessage() @ " << overlay->getThisNode().getAddress()
00336 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00337 << " Received a ScribeJoin for group " << key << "\n"
00338 << " msg=" << joinMsg
00339 << endl;
00340
00341
00342 pair<GroupList::iterator, bool> groupInserter;
00343 groupInserter = groupList.insert( make_pair(key, ScribeGroup(key)) );
00344
00345
00346 if ( !amIRoot && ( groupInserter.second || groupInserter.first->second.getParent().isUnspecified()) ) {
00347 ScribeJoinCall* newJoin = new ScribeJoinCall;
00348 newJoin->setGroupId( key );
00349 newJoin->setBitLength( SCRIBE_JOINCALL_L(newJoin) );
00350 sendRouteRpcCall(TIER1_COMP, key, newJoin);
00351 }
00352
00353
00354 if( groupInserter.first->second.numChildren() == 0 ) {
00355 ScribeTimer* heartbeat = new ScribeTimer("HeartbeatTimer");
00356 heartbeat->setTimerType( SCRIBE_HEARTBEAT );
00357 heartbeat->setGroup( groupInserter.first->second.getGroupId() );
00358 startTimer( heartbeat );
00359 if( ScribeTimer* t = groupInserter.first->second.getHeartbeatTimer() ){
00360
00361 if( t ) cancelAndDelete( t );
00362 }
00363 groupInserter.first->second.setHeartbeatTimer( heartbeat );
00364 }
00365
00366
00367 addChildToGroup( joinMsg->getSrcNode(), groupInserter.first->second );
00368
00369
00370 ScribeJoinResponse* joinResponse = new ScribeJoinResponse;
00371 joinResponse->setGroupId( key );
00372 joinResponse->setBitLength( SCRIBE_JOINRESPONSE_L(joinResponse) );
00373 sendRpcResponse( joinMsg, joinResponse );
00374 }
00375
00376 void Scribe::handlePublishCall( ScribePublishCall* publishCall )
00377 {
00378
00379 GroupList::iterator it = groupList.find( publishCall->getGroupId() );
00380 if( it == groupList.end() ||
00381 it->second.getParent().isUnspecified() ||
00382 it->second.getParent() != overlay->getThisNode() ){
00383
00384
00385 ScribePublishResponse* msg = new ScribePublishResponse("Wrong Root");
00386 msg->setGroupId( publishCall->getGroupId() );
00387 msg->setWrongRoot( true );
00388 msg->setBitLength( SCRIBE_PUBLISHRESPONSE_L(msg) );
00389 sendRpcResponse( publishCall, msg );
00390 } else {
00391 ScribeDataMessage* data = dynamic_cast<ScribeDataMessage*>(publishCall->decapsulate());
00392
00393 ScribePublishResponse* msg = new ScribePublishResponse("Publish Successful");
00394 msg->setGroupId( publishCall->getGroupId() );
00395 msg->setBitLength( SCRIBE_PUBLISHRESPONSE_L(msg) );
00396 sendRpcResponse( publishCall, msg );
00397
00398 if( !data ) {
00399
00400 EV << "[Scribe::handlePublishCall() @ " << overlay->getThisNode().getAddress()
00401 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00402 << " PublishCall for group " << msg->getGroupId()
00403 << " does not contain a calid ALM data message!\n"
00404 << endl;
00405 return;
00406 }
00407 deliverALMDataToGroup( data );
00408 }
00409 }
00410
00411 void Scribe::handleJoinResponse( ScribeJoinResponse* joinResponse )
00412 {
00413 GroupList::iterator it = groupList.find( joinResponse->getGroupId() );
00414 if( it == groupList.end() ) {
00415 EV << "[Scribe::handleJoinResponse() @ " << overlay->getThisNode().getAddress()
00416 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00417 << "Getting join response for an unknown group!\n";
00418 return;
00419 }
00420 it->second.setParent( joinResponse->getSrcNode() );
00421
00422
00423 ScribeTimer* parentTimeout = new ScribeTimer("ParentTimeoutTimer");
00424 parentTimeout->setTimerType( SCRIBE_PARENT_TIMEOUT );
00425 parentTimeout->setGroup( it->second.getGroupId() );
00426 startTimer( parentTimeout );
00427 if( ScribeTimer* t = it->second.getParentTimer() ){
00428
00429 if( t ) cancelAndDelete( t );
00430 }
00431 it->second.setParentTimer( parentTimeout );
00432 }
00433
00434 void Scribe::handlePublishResponse( ScribePublishResponse* publishResponse )
00435 {
00436 GroupList::iterator it = groupList.find( publishResponse->getGroupId() );
00437 if( it == groupList.end() ) {
00438 EV << "[Scribe::handlePublishResponse() @ " << overlay->getThisNode().getAddress()
00439 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00440 << "Getting publish response for an unknown group!\n";
00441 return;
00442 }
00443
00444 if( publishResponse->getWrongRoot() ) {
00445 it->second.setRendezvousPoint( NodeHandle::UNSPECIFIED_NODE );
00446 } else {
00447 it->second.setRendezvousPoint( publishResponse->getSrcNode() );
00448 }
00449 }
00450
00451 void Scribe::handleLeaveMessage( ScribeLeaveMessage* leaveMsg )
00452 {
00453 GroupList::iterator it = groupList.find( leaveMsg->getGroupId() );
00454 if( it != groupList.end() ){
00455 removeChildFromGroup( leaveMsg->getSrc(), it->second );
00456 }
00457 delete leaveMsg;
00458 }
00459
00460 void Scribe::subscribeToGroup( const OverlayKey& groupId )
00461 {
00462 EV << "[Scribe::subscribeToGroup() @ " << overlay->getThisNode().getAddress()
00463 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00464 << " Trying to join group " << groupId << "\n";
00465
00466
00467 pair<GroupList::iterator, bool> groupInserter;
00468 groupInserter = groupList.insert( make_pair(groupId, ScribeGroup(groupId)) );
00469
00470
00471 groupInserter.first->second.setSubscription(true);
00472
00473
00474 if( groupInserter.second || groupInserter.first->second.getParent().isUnspecified()) {
00475 ScribeJoinCall* m = new ScribeJoinCall;
00476 m->setGroupId( groupId );
00477 m->setBitLength( SCRIBE_JOINCALL_L(m) );
00478 sendRouteRpcCall(TIER1_COMP, m->getGroupId(), m);
00479 }
00480 }
00481
00482 void Scribe::leaveGroup( const OverlayKey& group )
00483 {
00484 GroupList::iterator it = groupList.find( group );
00485 if( it != groupList.end() ){
00486 it->second.setSubscription( false );
00487 checkGroupEmpty( it->second );
00488 }
00489 }
00490
00491 void Scribe::addChildToGroup( const NodeHandle& child, ScribeGroup& group )
00492 {
00493 if( child == overlay->getThisNode() ) {
00494
00495 return;
00496 }
00497
00498
00499 pair<set<NodeHandle>::iterator, bool> inserter =
00500 group.addChild( child );
00501
00502 if( inserter.second ) {
00503
00504 ScribeTimer* timeoutMsg = new ScribeTimer;
00505 timeoutMsg->setTimerType( SCRIBE_CHILD_TIMEOUT );
00506
00507
00508 timeoutMsg->setChild( *inserter.first );
00509 timeoutMsg->setGroup( group.getGroupId() );
00510
00511 startTimer( timeoutMsg );
00512 childTimeoutList.insert( make_pair(child, timeoutMsg) );
00513 }
00514 }
00515
00516 void Scribe::removeChildFromGroup( const NodeHandle& child, ScribeGroup& group )
00517 {
00518
00519 ScribeTimer* timer = NULL;
00520 pair<ChildTimeoutList::iterator, ChildTimeoutList::iterator> ret =
00521 childTimeoutList.equal_range( child );
00522 if( ret.first != childTimeoutList.end() ){
00523 for( ChildTimeoutList::iterator it = ret.first; it!=ret.second; ++it) {
00524 if( group == it->second->getGroup() ) {
00525 timer = it->second;
00526 childTimeoutList.erase( it );
00527 cancelAndDelete( timer );
00528 break;
00529 }
00530 }
00531 }
00532
00533
00534 group.removeChild( child );
00535
00536 checkGroupEmpty( group );
00537 }
00538
00539 void Scribe::removeChildFromGroup( ScribeTimer* timer )
00540 {
00541 NodeHandle& child = timer->getChild();
00542
00543 GroupList::iterator groupIt = groupList.find( timer->getGroup() );
00544 if( groupIt != groupList.end() ) {
00545 ScribeGroup& group = groupIt->second;
00546
00547 group.removeChild( child );
00548
00549 checkGroupEmpty( group );
00550 }
00551
00552
00553 pair<ChildTimeoutList::iterator, ChildTimeoutList::iterator> ret =
00554 childTimeoutList.equal_range( child );
00555 if( ret.first != childTimeoutList.end() ) {
00556 for( ChildTimeoutList::iterator it = ret.first; it!=ret.second; ++it) {
00557 if( it->second == timer ) {
00558 childTimeoutList.erase( it );
00559 cancelAndDelete( timer );
00560 break;
00561 }
00562 }
00563 }
00564 }
00565
00566 void Scribe::checkGroupEmpty( ScribeGroup& group )
00567 {
00568 if( !group.isForwarder() && !group.getSubscription() && !group.getAmISource()){
00569
00570 if( !group.getParent().isUnspecified() && group.getParent() != overlay->getThisNode() ) {
00571
00572 ScribeLeaveMessage* msg = new ScribeLeaveMessage("Leave");
00573 msg->setGroupId( group.getGroupId() );
00574 msg->setSrc( overlay->getThisNode() );
00575 msg->setBitLength( SCRIBE_LEAVE_L(msg) );
00576 callRoute( OverlayKey::UNSPECIFIED_KEY, msg, group.getParent() );
00577 }
00578
00579 if( group.getParentTimer() ) cancelAndDelete( group.getParentTimer() );
00580 if( group.getHeartbeatTimer() ) cancelAndDelete( group.getHeartbeatTimer() );
00581 groupList.erase( group.getGroupId() );
00582 }
00583 }
00584
00585 void Scribe::refreshChildTimer( NodeHandle& child, OverlayKey& groupId )
00586 {
00587
00588 pair<ChildTimeoutList::iterator, ChildTimeoutList::iterator> ret =
00589 childTimeoutList.equal_range( child );
00590
00591 if( ret.first == childTimeoutList.end() ) return;
00592
00593
00594 for( ChildTimeoutList::iterator it = ret.first; it!=ret.second; ++it) {
00595 if( it->first == child && it->second->getGroup() == groupId ) {
00596 startTimer( it->second );
00597 }
00598 }
00599 }
00600
00601 void Scribe::startTimer( ScribeTimer* timer )
00602 {
00603 if( timer->isScheduled() ) {
00604 cancelEvent( timer );
00605 }
00606
00607 int duration = 0;
00608 switch( timer->getTimerType() ) {
00609 case SCRIBE_HEARTBEAT:
00610 duration = parentTimeout/2;
00611 break;
00612 case SCRIBE_SUBSCRIPTION_REFRESH:
00613 duration = childTimeout/2;
00614 break;
00615 case SCRIBE_PARENT_TIMEOUT:
00616 duration = parentTimeout;
00617 break;
00618 case SCRIBE_CHILD_TIMEOUT:
00619 duration = childTimeout;
00620 break;
00621 }
00622 scheduleAt(simTime() + duration, timer );
00623 }
00624
00625 void Scribe::deliverALMDataToRoot( ALMMulticastMessage* mcastMsg )
00626 {
00627
00628 pair<GroupList::iterator, bool> groupInserter;
00629 groupInserter = groupList.insert( make_pair(mcastMsg->getGroupId(), ScribeGroup(mcastMsg->getGroupId())) );
00630
00631
00632 if( groupInserter.second ) {
00633 groupInserter.first->second.setAmISource( true );
00634
00635
00636
00637
00638
00639
00640 }
00641
00642 ScribeDataMessage* dataMsg = new ScribeDataMessage( mcastMsg->getName() );
00643 dataMsg->setGroupId( mcastMsg->getGroupId() );
00644 dataMsg->setBitLength( SCRIBE_DATA_L( dataMsg ));
00645 dataMsg->encapsulate( mcastMsg->decapsulate() );
00646
00647
00648 ScribePublishCall* msg = new ScribePublishCall( "ScribePublish" );
00649 msg->setGroupId( dataMsg->getGroupId() );
00650 msg->setBitLength( SCRIBE_PUBLISHCALL_L(msg) );
00651 msg->encapsulate( dataMsg );
00652
00653 if( !groupInserter.first->second.getRendezvousPoint().isUnspecified() ) {
00654
00655 sendRouteRpcCall(TIER1_COMP, groupInserter.first->second.getRendezvousPoint(), msg);
00656 } else {
00657
00658 sendRouteRpcCall(TIER1_COMP, msg->getGroupId(), msg);
00659 }
00660
00661 delete mcastMsg;
00662 }
00663
00664
00665 void Scribe::deliverALMDataToGroup( ScribeDataMessage* dataMsg )
00666 {
00667
00668 GroupList::iterator it = groupList.find( dataMsg->getGroupId() );
00669 if( it == groupList.end() ) {
00670 EV << "[Scribe::deliverALMDataToGroup() @ " << overlay->getThisNode().getAddress()
00671 << "Getting ALM data message response for an unknown group!\n";
00672 delete dataMsg;
00673 return;
00674 }
00675
00676
00677
00678 ScribeTimer *timer = it->second.getParentTimer();
00679 if( timer ) startTimer( timer );
00680
00681
00682 if( dataMsg->getEmpty() ) {
00683 delete dataMsg;
00684 return;
00685 }
00686
00687
00688 for( set<NodeHandle>::iterator cit = it->second.getChildrenBegin();
00689 cit != it->second.getChildrenEnd(); ++cit ) {
00690 ScribeDataMessage* newMsg = new ScribeDataMessage( *dataMsg );
00691 RECORD_STATS(++numForward; forwardBytes += newMsg->getByteLength());
00692 callRoute( OverlayKey::UNSPECIFIED_KEY, newMsg, *cit );
00693 }
00694
00695
00696 if( it->second.getSubscription() ) {
00697 ALMMulticastMessage* mcastMsg = new ALMMulticastMessage( dataMsg->getName() );
00698 mcastMsg->setGroupId( dataMsg->getGroupId() );
00699 mcastMsg->encapsulate( dataMsg->decapsulate() );
00700 RECORD_STATS(++numReceived; receivedBytes += dataMsg->getByteLength());
00701 send( mcastMsg, "to_upperTier" );
00702 }
00703
00704 delete dataMsg;
00705 }
00706