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) && msg->getReady() ) {
00231
00232
00233 CompReadyMessage* readyMsg = new CompReadyMessage;
00234 readyMsg->setReady( true );
00235 readyMsg->setComp( getThisCompType() );
00236
00237 send( readyMsg, "to_upperTier" );
00238
00239 startTimer( subscriptionTimer );
00240 }
00241 delete msg;
00242 }
00243
00244 void Scribe::handleTimerEvent( cMessage *msg )
00245 {
00246 ScribeTimer* timer = dynamic_cast<ScribeTimer*>(msg);
00247 assert( timer );
00248 switch( timer->getTimerType() ) {
00249 case SCRIBE_SUBSCRIPTION_REFRESH:
00250
00251 for( GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it ) {
00252 NodeHandle parent = it->second.getParent();
00253 if( !parent.isUnspecified() ){
00254 ScribeSubscriptionRefreshMessage* refreshMsg = new ScribeSubscriptionRefreshMessage;
00255 refreshMsg->setGroupId( it->second.getGroupId() );
00256 refreshMsg->setSrc( overlay->getThisNode() );
00257
00258 refreshMsg->setBitLength(SCRIBE_SUBSCRIPTIONREFRESH_L(refreshMsg));
00259 RECORD_STATS(++numSubscriptionRefresh;
00260 subscriptionRefreshBytes += refreshMsg->getByteLength()
00261 );
00262 callRoute( OverlayKey::UNSPECIFIED_KEY, refreshMsg, parent );
00263 }
00264 }
00265 startTimer( subscriptionTimer );
00266 break;
00267
00268 case SCRIBE_HEARTBEAT:
00269 {
00270
00271 GroupList::iterator groupIt = groupList.find( timer->getGroup() );
00272 if( groupIt == groupList.end() ) {
00273
00274 delete timer;
00275 return;
00276 }
00277 for( set<NodeHandle>::iterator it = groupIt->second.getChildrenBegin();
00278 it != groupIt->second.getChildrenEnd(); ++it ) {
00279 ScribeDataMessage* heartbeatMsg = new ScribeDataMessage("Heartbeat");
00280 heartbeatMsg->setEmpty( true );
00281 heartbeatMsg->setGroupId( timer->getGroup() );
00282
00283 heartbeatMsg->setBitLength(SCRIBE_DATA_L(heartbeatMsg));
00284 RECORD_STATS(++numHeartbeat; heartbeatBytes += heartbeatMsg->getByteLength());
00285 callRoute( OverlayKey::UNSPECIFIED_KEY, heartbeatMsg, *it );
00286 }
00287 startTimer( timer );
00288 break;
00289 }
00290 case SCRIBE_CHILD_TIMEOUT:
00291
00292 RECORD_STATS(++numChildTimeout);
00293 removeChildFromGroup( timer );
00294 break;
00295
00296 case SCRIBE_PARENT_TIMEOUT:
00297
00298 RECORD_STATS(++numParentTimeout);
00299 OverlayKey key = timer->getGroup();
00300 EV << "[Scribe::handleTimerEvent() @ " << overlay->getThisNode().getAddress()
00301 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00302 << " Parent of group " << key << "\n"
00303 << " failed to send heartbeat, trying to rejoin"
00304 << endl;
00305
00306 ScribeJoinCall* newJoin = new ScribeJoinCall;
00307 newJoin->setGroupId( key );
00308 newJoin->setBitLength( SCRIBE_JOINCALL_L(newJoin) );
00309 sendRouteRpcCall(TIER1_COMP, key, newJoin);
00310
00311 GroupList::iterator groupIt = groupList.find( timer->getGroup() );
00312 if( groupIt == groupList.end() ) {
00313
00314 delete timer;
00315 return;
00316 }
00317 groupIt->second.setParentTimer( NULL );
00318 cancelAndDelete( timer );
00319 break;
00320 }
00321
00322 }
00323
00324 void Scribe::handleJoinCall( ScribeJoinCall* joinMsg)
00325 {
00326 handleJoinMessage( joinMsg, true );
00327 }
00328
00329 void Scribe::handleJoinMessage( ScribeJoinCall* joinMsg, bool amIRoot)
00330 {
00331 RECORD_STATS(++numJoins);
00332 OverlayKey key = joinMsg->getGroupId();
00333
00334 EV << "[Scribe::handleJoinMessage() @ " << overlay->getThisNode().getAddress()
00335 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00336 << " Received a ScribeJoin for group " << key << "\n"
00337 << " msg=" << joinMsg
00338 << endl;
00339
00340
00341 pair<GroupList::iterator, bool> groupInserter;
00342 groupInserter = groupList.insert( make_pair(key, ScribeGroup(key)) );
00343
00344
00345 if ( !amIRoot && ( groupInserter.second || groupInserter.first->second.getParent().isUnspecified()) ) {
00346 ScribeJoinCall* newJoin = new ScribeJoinCall;
00347 newJoin->setGroupId( key );
00348 newJoin->setBitLength( SCRIBE_JOINCALL_L(newJoin) );
00349 sendRouteRpcCall(TIER1_COMP, key, newJoin);
00350 }
00351
00352
00353 if( groupInserter.first->second.numChildren() == 0 ) {
00354 ScribeTimer* heartbeat = new ScribeTimer("HeartbeatTimer");
00355 heartbeat->setTimerType( SCRIBE_HEARTBEAT );
00356 heartbeat->setGroup( groupInserter.first->second.getGroupId() );
00357 startTimer( heartbeat );
00358 if( ScribeTimer* t = groupInserter.first->second.getHeartbeatTimer() ){
00359
00360 if( t ) cancelAndDelete( t );
00361 }
00362 groupInserter.first->second.setHeartbeatTimer( heartbeat );
00363 }
00364
00365
00366 addChildToGroup( joinMsg->getSrcNode(), groupInserter.first->second );
00367
00368
00369 ScribeJoinResponse* joinResponse = new ScribeJoinResponse;
00370 joinResponse->setGroupId( key );
00371 joinResponse->setBitLength( SCRIBE_JOINRESPONSE_L(joinResponse) );
00372 sendRpcResponse( joinMsg, joinResponse );
00373 }
00374
00375 void Scribe::handlePublishCall( ScribePublishCall* publishCall )
00376 {
00377
00378 GroupList::iterator it = groupList.find( publishCall->getGroupId() );
00379 if( it == groupList.end() ||
00380 it->second.getParent().isUnspecified() ||
00381 it->second.getParent() != overlay->getThisNode() ){
00382
00383
00384 ScribePublishResponse* msg = new ScribePublishResponse("Wrong Root");
00385 msg->setGroupId( publishCall->getGroupId() );
00386 msg->setWrongRoot( true );
00387 msg->setBitLength( SCRIBE_PUBLISHRESPONSE_L(msg) );
00388 sendRpcResponse( publishCall, msg );
00389 } else {
00390 ScribeDataMessage* data = dynamic_cast<ScribeDataMessage*>(publishCall->decapsulate());
00391
00392 ScribePublishResponse* msg = new ScribePublishResponse("Publish Successful");
00393 msg->setGroupId( publishCall->getGroupId() );
00394 msg->setBitLength( SCRIBE_PUBLISHRESPONSE_L(msg) );
00395 sendRpcResponse( publishCall, msg );
00396
00397 if( !data ) {
00398
00399 EV << "[Scribe::handlePublishCall() @ " << overlay->getThisNode().getAddress()
00400 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00401 << " PublishCall for group " << msg->getGroupId()
00402 << " does not contain a calid ALM data message!\n"
00403 << endl;
00404 return;
00405 }
00406 deliverALMDataToGroup( data );
00407 }
00408 }
00409
00410 void Scribe::handleJoinResponse( ScribeJoinResponse* joinResponse )
00411 {
00412 GroupList::iterator it = groupList.find( joinResponse->getGroupId() );
00413 if( it == groupList.end() ) {
00414 EV << "[Scribe::handleJoinResponse() @ " << overlay->getThisNode().getAddress()
00415 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00416 << "Getting join response for an unknown group!\n";
00417 return;
00418 }
00419 it->second.setParent( joinResponse->getSrcNode() );
00420
00421
00422 ScribeTimer* parentTimeout = new ScribeTimer("ParentTimeoutTimer");
00423 parentTimeout->setTimerType( SCRIBE_PARENT_TIMEOUT );
00424 parentTimeout->setGroup( it->second.getGroupId() );
00425 startTimer( parentTimeout );
00426 if( ScribeTimer* t = it->second.getParentTimer() ){
00427
00428 if( t ) cancelAndDelete( t );
00429 }
00430 it->second.setParentTimer( parentTimeout );
00431 }
00432
00433 void Scribe::handlePublishResponse( ScribePublishResponse* publishResponse )
00434 {
00435 GroupList::iterator it = groupList.find( publishResponse->getGroupId() );
00436 if( it == groupList.end() ) {
00437 EV << "[Scribe::handlePublishResponse() @ " << overlay->getThisNode().getAddress()
00438 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00439 << "Getting publish response for an unknown group!\n";
00440 return;
00441 }
00442
00443 if( publishResponse->getWrongRoot() ) {
00444 it->second.setRendezvousPoint( NodeHandle::UNSPECIFIED_NODE );
00445 } else {
00446 it->second.setRendezvousPoint( publishResponse->getSrcNode() );
00447 }
00448 }
00449
00450 void Scribe::handleLeaveMessage( ScribeLeaveMessage* leaveMsg )
00451 {
00452 GroupList::iterator it = groupList.find( leaveMsg->getGroupId() );
00453 if( it != groupList.end() ){
00454 removeChildFromGroup( leaveMsg->getSrc(), it->second );
00455 }
00456 delete leaveMsg;
00457 }
00458
00459 void Scribe::subscribeToGroup( const OverlayKey& groupId )
00460 {
00461 EV << "[Scribe::subscribeToGroup() @ " << overlay->getThisNode().getAddress()
00462 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00463 << " Trying to join group " << groupId << "\n";
00464
00465
00466 pair<GroupList::iterator, bool> groupInserter;
00467 groupInserter = groupList.insert( make_pair(groupId, ScribeGroup(groupId)) );
00468
00469
00470 groupInserter.first->second.setSubscription(true);
00471
00472
00473 if( groupInserter.second || groupInserter.first->second.getParent().isUnspecified()) {
00474 ScribeJoinCall* m = new ScribeJoinCall;
00475 m->setGroupId( groupId );
00476 m->setBitLength( SCRIBE_JOINCALL_L(m) );
00477 sendRouteRpcCall(TIER1_COMP, m->getGroupId(), m);
00478 }
00479 }
00480
00481 void Scribe::leaveGroup( const OverlayKey& group )
00482 {
00483 GroupList::iterator it = groupList.find( group );
00484 if( it != groupList.end() ){
00485 it->second.setSubscription( false );
00486 checkGroupEmpty( it->second );
00487 }
00488 }
00489
00490 void Scribe::addChildToGroup( const NodeHandle& child, ScribeGroup& group )
00491 {
00492 if( child == overlay->getThisNode() ) {
00493
00494 return;
00495 }
00496
00497
00498 pair<set<NodeHandle>::iterator, bool> inserter =
00499 group.addChild( child );
00500
00501 if( inserter.second ) {
00502
00503 ScribeTimer* timeoutMsg = new ScribeTimer;
00504 timeoutMsg->setTimerType( SCRIBE_CHILD_TIMEOUT );
00505
00506
00507 timeoutMsg->setChild( *inserter.first );
00508 timeoutMsg->setGroup( group.getGroupId() );
00509
00510 startTimer( timeoutMsg );
00511 childTimeoutList.insert( make_pair(child, timeoutMsg) );
00512 }
00513 }
00514
00515 void Scribe::removeChildFromGroup( const NodeHandle& child, ScribeGroup& group )
00516 {
00517
00518 ScribeTimer* timer = NULL;
00519 pair<ChildTimeoutList::iterator, ChildTimeoutList::iterator> ret =
00520 childTimeoutList.equal_range( child );
00521 if( ret.first != childTimeoutList.end() ){
00522 for( ChildTimeoutList::iterator it = ret.first; it!=ret.second; ++it) {
00523 if( group == it->second->getGroup() ) {
00524 timer = it->second;
00525 childTimeoutList.erase( it );
00526 cancelAndDelete( timer );
00527 break;
00528 }
00529 }
00530 }
00531
00532
00533 group.removeChild( child );
00534
00535 checkGroupEmpty( group );
00536 }
00537
00538 void Scribe::removeChildFromGroup( ScribeTimer* timer )
00539 {
00540 NodeHandle& child = timer->getChild();
00541
00542 GroupList::iterator groupIt = groupList.find( timer->getGroup() );
00543 if( groupIt != groupList.end() ) {
00544 ScribeGroup& group = groupIt->second;
00545
00546 group.removeChild( child );
00547
00548 checkGroupEmpty( group );
00549 }
00550
00551
00552 pair<ChildTimeoutList::iterator, ChildTimeoutList::iterator> ret =
00553 childTimeoutList.equal_range( child );
00554 if( ret.first != childTimeoutList.end() ) {
00555 for( ChildTimeoutList::iterator it = ret.first; it!=ret.second; ++it) {
00556 if( it->second == timer ) {
00557 childTimeoutList.erase( it );
00558 cancelAndDelete( timer );
00559 break;
00560 }
00561 }
00562 }
00563 }
00564
00565 void Scribe::checkGroupEmpty( ScribeGroup& group )
00566 {
00567 if( !group.isForwarder() && !group.getSubscription() && !group.getAmISource()){
00568
00569 if( !group.getParent().isUnspecified() && group.getParent() != overlay->getThisNode() ) {
00570
00571 ScribeLeaveMessage* msg = new ScribeLeaveMessage("Leave");
00572 msg->setGroupId( group.getGroupId() );
00573 msg->setSrc( overlay->getThisNode() );
00574 msg->setBitLength( SCRIBE_LEAVE_L(msg) );
00575 callRoute( OverlayKey::UNSPECIFIED_KEY, msg, group.getParent() );
00576 }
00577
00578 if( group.getParentTimer() ) cancelAndDelete( group.getParentTimer() );
00579 if( group.getHeartbeatTimer() ) cancelAndDelete( group.getHeartbeatTimer() );
00580 groupList.erase( group.getGroupId() );
00581 }
00582 }
00583
00584 void Scribe::refreshChildTimer( NodeHandle& child, OverlayKey& groupId )
00585 {
00586
00587 pair<ChildTimeoutList::iterator, ChildTimeoutList::iterator> ret =
00588 childTimeoutList.equal_range( child );
00589
00590 if( ret.first == childTimeoutList.end() ) return;
00591
00592
00593 for( ChildTimeoutList::iterator it = ret.first; it!=ret.second; ++it) {
00594 if( it->first == child && it->second->getGroup() == groupId ) {
00595 startTimer( it->second );
00596 }
00597 }
00598 }
00599
00600 void Scribe::startTimer( ScribeTimer* timer )
00601 {
00602 if( timer->isScheduled() ) {
00603 cancelEvent( timer );
00604 }
00605
00606 int duration = 0;
00607 switch( timer->getTimerType() ) {
00608 case SCRIBE_HEARTBEAT:
00609 duration = parentTimeout/2;
00610 break;
00611 case SCRIBE_SUBSCRIPTION_REFRESH:
00612 duration = childTimeout/2;
00613 break;
00614 case SCRIBE_PARENT_TIMEOUT:
00615 duration = parentTimeout;
00616 break;
00617 case SCRIBE_CHILD_TIMEOUT:
00618 duration = childTimeout;
00619 break;
00620 }
00621 scheduleAt(simTime() + duration, timer );
00622 }
00623
00624 void Scribe::deliverALMDataToRoot( ALMMulticastMessage* mcastMsg )
00625 {
00626
00627 pair<GroupList::iterator, bool> groupInserter;
00628 groupInserter = groupList.insert( make_pair(mcastMsg->getGroupId(), ScribeGroup(mcastMsg->getGroupId())) );
00629
00630
00631 if( groupInserter.second ) {
00632 groupInserter.first->second.setAmISource( true );
00633
00634
00635
00636
00637
00638
00639 }
00640
00641 ScribeDataMessage* dataMsg = new ScribeDataMessage( mcastMsg->getName() );
00642 dataMsg->setGroupId( mcastMsg->getGroupId() );
00643 dataMsg->setBitLength( SCRIBE_DATA_L( dataMsg ));
00644 dataMsg->encapsulate( mcastMsg->decapsulate() );
00645
00646
00647 ScribePublishCall* msg = new ScribePublishCall( "ScribePublish" );
00648 msg->setGroupId( dataMsg->getGroupId() );
00649 msg->setBitLength( SCRIBE_PUBLISHCALL_L(msg) );
00650 msg->encapsulate( dataMsg );
00651
00652 if( !groupInserter.first->second.getRendezvousPoint().isUnspecified() ) {
00653
00654 sendRouteRpcCall(TIER1_COMP, groupInserter.first->second.getRendezvousPoint(), msg);
00655 } else {
00656
00657 sendRouteRpcCall(TIER1_COMP, msg->getGroupId(), msg);
00658 }
00659
00660 delete mcastMsg;
00661 }
00662
00663
00664 void Scribe::deliverALMDataToGroup( ScribeDataMessage* dataMsg )
00665 {
00666
00667 GroupList::iterator it = groupList.find( dataMsg->getGroupId() );
00668 if( it == groupList.end() ) {
00669 EV << "[Scribe::deliverALMDataToGroup() @ " << overlay->getThisNode().getAddress()
00670 << "Getting ALM data message response for an unknown group!\n";
00671 delete dataMsg;
00672 return;
00673 }
00674
00675
00676
00677 ScribeTimer *timer = it->second.getParentTimer();
00678 if( timer ) startTimer( timer );
00679
00680
00681 if( dataMsg->getEmpty() ) {
00682 delete dataMsg;
00683 return;
00684 }
00685
00686
00687 for( set<NodeHandle>::iterator cit = it->second.getChildrenBegin();
00688 cit != it->second.getChildrenEnd(); ++cit ) {
00689 ScribeDataMessage* newMsg = new ScribeDataMessage( *dataMsg );
00690 RECORD_STATS(++numForward; forwardBytes += newMsg->getByteLength());
00691 callRoute( OverlayKey::UNSPECIFIED_KEY, newMsg, *cit );
00692 }
00693
00694
00695 if( it->second.getSubscription() ) {
00696 ALMMulticastMessage* mcastMsg = new ALMMulticastMessage( dataMsg->getName() );
00697 mcastMsg->setGroupId( dataMsg->getGroupId() );
00698 mcastMsg->encapsulate( dataMsg->decapsulate() );
00699 RECORD_STATS(++numReceived; receivedBytes += dataMsg->getByteLength());
00700 send( mcastMsg, "to_upperTier" );
00701 }
00702
00703 delete dataMsg;
00704 }
00705