#include <PubSubMMOG.h>
Public Member Functions | |
virtual | ~PubSubMMOG () |
virtual void | initializeOverlay (int stage) |
Initializes derived-class-attributes. | |
virtual void | finishOverlay () |
collects statistical data in derived class | |
virtual void | handleUDPMessage (BaseOverlayMessage *msg) |
Processes messages from underlay. | |
virtual void | handleTimerEvent (cMessage *msg) |
virtual void | handleAppMessage (cMessage *msg) |
Processes "timer" self-messages. | |
virtual void | receiveChangeNotification (int category, const cPolymorphic *details) |
callback-method for events at the NotificationBoard | |
virtual bool | handleRpcCall (BaseCallMessage *msg) |
Processes Remote-Procedure-Call invocation messages. | |
virtual void | handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
virtual void | handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey) |
This method is called if an RPC timeout has been reached. | |
Protected Member Functions | |
void | setBootstrapedIcon () |
void | handleMove (GameAPIPositionMessage *posMsg) |
void | handleMoveMessage (PubSubMoveMessage *moveMsg) |
void | handleMoveListMessage (PubSubMoveListMessage *moveMsg) |
void | handleJoinResponse (PubSubJoinResponse *joinResp) |
void | handleSubscriptionCall (PubSubSubscriptionCall *subCall) |
void | handleSubscriptionResponse (PubSubSubscriptionResponse *subResp) |
void | handleResponsibleNodeResponse (PubSubResponsibleNodeResponse *subResp) |
void | handleTakeOver (PubSubTakeOverSubspaceCall *toCall) |
void | handleHelpResponse (PubSubHelpResponse *helpResp) |
void | handleBackupCall (PubSubBackupCall *backupCall) |
void | handleBackupResponse (PubSubBackupResponse *backupResp) |
void | handleIntermediateCall (PubSubIntermediateCall *intermediateCall) |
void | handleIntermediateResponse (PubSubIntermediateResponse *intermediateResp) |
void | handleAdoptChildCall (PubSubAdoptChildCall *adoptCall) |
void | handleAdoptChildResponse (PubSubAdoptChildResponse *adoptResp) |
void | handlePingCall (PubSubPingCall *hearbeatCall) |
void | handlePingResponse (PubSubPingResponse *pingResp) |
void | takeOverNewSubspace (PubSubSubspaceId subspaceId) |
void | takeOverSubspace (PubSubSubspaceResponsible &subspaceId, bool isNew) |
void | sendHearbeatToChildren () |
void | sendPingToChildren () |
void | handleParentTimeout (PubSubTimer *timer) |
void | handleBackupCallTimeout (PubSubBackupCall *backupCall, const TransportAddress &oldNode) |
void | handlePingCallTimeout (PubSubPingCall *pingCall, const TransportAddress &oldNode) |
void | handleSubscriptionCallTimeout (PubSubSubscriptionCall *subscriptionCall, const TransportAddress &oldNode) |
void | handleUnsubscriptionMessage (PubSubUnsubscriptionMessage *unsMsg) |
void | handleNodeLeftMessage (PubSubNodeLeftMessage *leftMsg) |
void | handleReplacementMessage (PubSubReplacementMessage *replaceMsg) |
void | handleReleaseIntermediate (PubSubReleaseIntermediateMessage *releaseMsg) |
void | handleIntermediateBackup (PubSubBackupIntermediateMessage *backupMsg) |
void | handleSubscriptionBackup (PubSubBackupSubscriptionMessage *backupMsg) |
void | handleUnsubscribeBackup (PubSubBackupUnsubscribeMessage *backupMsg) |
void | unsubscribeChild (const NodeHandle &node, PubSubSubspaceResponsible &subspace) |
void | sendMessageToChildren (PubSubSubspaceResponsible &subspace, BaseOverlayMessage *toIntermediates, BaseOverlayMessage *toBackup, BaseOverlayMessage *toPlayers) |
void | publishEvents () |
void | startTimer (PubSubTimer *timer) |
Protected Attributes | |
std::list< PubSubSubspace > | subscribedSubspaces |
std::map< PubSubSubspaceId, PubSubSubspaceResponsible > | responsibleSubspaces |
std::map< PubSubSubspaceId, PubSubSubspaceResponsible > | backupSubspaces |
std::map< PubSubSubspaceId, PubSubSubspaceIntermediate > | intermediateSubspaces |
int | subspaceSize |
int | AOIWidth |
int | numSubspaces |
int | parentTimeout |
int | maxChildren |
bool | allowOldMoveMessages |
unsigned int | currentRegionX |
unsigned int | currentRegionY |
int | movementRate |
int | maxMoveDelay |
PubSubTimer * | heartbeatTimer |
PubSubTimer * | childPingTimer |
PubSubTimer * | eventDeliveryTimer |
cMessage * | joinTimer |
TransportAddress | lobbyServer |
int | numEventsWrongTimeslot |
int | numEventsCorrectTimeslot |
int | numPubSubSignalingMessages |
int | pubSubSignalingMessagesSize |
int | numMoveMessages |
int | moveMessagesSize |
int | numMoveListMessages |
int | moveListMessagesSize |
int | respMoveListMessagesSize |
int | lostMovementLists |
int | receivedMovementLists |
Definition at line 33 of file PubSubMMOG.h.
PubSubMMOG::~PubSubMMOG | ( | ) | [virtual] |
Definition at line 2006 of file PubSubMMOG.cc.
02007 { 02008 // Delete all waiting move messages 02009 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 02010 for( it = responsibleSubspaces.begin(); it != responsibleSubspaces.end(); ++it) { 02011 deque<PubSubMoveMessage*>::iterator msgIt; 02012 for( msgIt = it->second.waitingMoveMessages.begin(); msgIt != it->second.waitingMoveMessages.end(); ++msgIt ){ 02013 cancelAndDelete( *msgIt ); 02014 } 02015 it->second.waitingMoveMessages.clear(); 02016 } 02017 02018 cancelAndDelete(heartbeatTimer); 02019 }
void PubSubMMOG::finishOverlay | ( | ) | [virtual] |
collects statistical data in derived class
Reimplemented from BaseOverlay.
Definition at line 1977 of file PubSubMMOG.cc.
01978 { 01979 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 01980 if (time < GlobalStatistics::MIN_MEASURED) return; 01981 01982 globalStatistics->addStdDev("PubSubMMOG: Sent Signaling Messages/s", 01983 numPubSubSignalingMessages / time); 01984 globalStatistics->addStdDev("PubSubMMOG: Sent Signaling bytes/s", 01985 pubSubSignalingMessagesSize / time); 01986 globalStatistics->addStdDev("PubSubMMOG: Sent Move Messages/s", 01987 numMoveMessages / time); 01988 globalStatistics->addStdDev("PubSubMMOG: Sent Move bytes/s", 01989 moveMessagesSize / time); 01990 globalStatistics->addStdDev("PubSubMMOG: Sent MoveList Messages/s", 01991 numMoveListMessages / time); 01992 globalStatistics->addStdDev("PubSubMMOG: Sent MoveList bytes/s", 01993 moveListMessagesSize / time); 01994 globalStatistics->addStdDev("PubSubMMOG: Received Move Events (correct timeslot)/s", 01995 numEventsCorrectTimeslot / time); 01996 globalStatistics->addStdDev("PubSubMMOG: Received Move Events (wrong timeslot)/s", 01997 numEventsWrongTimeslot / time); 01998 globalStatistics->addStdDev("PubSubMMOG: Responsible Nodes: Send MoveList Bytes/s", 01999 respMoveListMessagesSize / time); 02000 globalStatistics->addStdDev("PubSubMMOG: Lost or too long delayed MoveLists/s", 02001 lostMovementLists / time); 02002 globalStatistics->addStdDev("PubSubMMOG: Received valid MoveLists/s", 02003 receivedMovementLists / time); 02004 }
void PubSubMMOG::handleAdoptChildCall | ( | PubSubAdoptChildCall * | adoptCall | ) | [protected] |
Definition at line 1026 of file PubSubMMOG.cc.
Referenced by handleRpcCall().
01027 { 01028 std::map<PubSubSubspaceId, PubSubSubspaceIntermediate>::iterator it; 01029 it = intermediateSubspaces.find( PubSubSubspaceId(adoptCall->getSubspaceId(), numSubspaces) ); 01030 if( it == intermediateSubspaces.end() ) { 01031 EV << "[PubSubMMOG::handleAdoptChildCall() @ " << thisNode.getAddress() 01032 << " (" << thisNode.getKey().toString(16) << ")]\n" 01033 << " Received Adopt Child Call for unknown Subspace!\n" 01034 << endl; 01035 cancelAndDelete( adoptCall ); 01036 return; 01037 } 01038 01039 it->second.addChild( adoptCall->getChild() ); 01040 PubSubAdoptChildResponse* adoptResp = new PubSubAdoptChildResponse("I adopted child"); 01041 adoptResp->setSubspaceId( adoptCall->getSubspaceId() ); 01042 adoptResp->setChild( adoptCall->getChild() ); 01043 adoptResp->setBitLength( PUBSUB_ADOPTCHILDRESPONSE_L( adoptResp )); 01044 RECORD_STATS( 01045 ++numPubSubSignalingMessages; 01046 pubSubSignalingMessagesSize+= adoptResp->getByteLength() 01047 ); 01048 sendRpcResponse( adoptCall, adoptResp ); 01049 }
void PubSubMMOG::handleAdoptChildResponse | ( | PubSubAdoptChildResponse * | adoptResp | ) | [protected] |
Definition at line 1051 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
01052 { 01053 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01054 it = responsibleSubspaces.find( PubSubSubspaceId(adoptResp->getSubspaceId(), numSubspaces) ); 01055 if( it == responsibleSubspaces.end() ) { 01056 EV << "[PubSubMMOG::handleAdoptChildResponse() @ " << thisNode.getAddress() 01057 << " (" << thisNode.getKey().toString(16) << ")]\n" 01058 << " Received AdoptChild Response for unknown Subspace!\n" 01059 << endl; 01060 return; 01061 } 01062 01063 // FIXME: just for testing 01064 PubSubSubspaceResponsible& subspace = it->second; 01065 int iii = subspace.getTotalChildrenCount(); 01066 subspace.fixTotalChildrenCount(); 01067 if( iii != subspace.getTotalChildrenCount() ){ 01068 opp_error("Huh?"); 01069 } 01070 01071 // Find intermediate node in subspace 01072 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 01073 for( iit = it->second.intermediateNodes.begin(); iit != it->second.intermediateNodes.end(); ++iit ){ 01074 if( !iit->node.isUnspecified() && iit->node == adoptResp->getSrcNode() ){ 01075 01076 // if adoption was for a child intermediate node, nothing is to be done 01077 int intermediatePos = iit - it->second.intermediateNodes.begin(); 01078 for( int pos = (intermediatePos+1) * maxChildren; pos < (int) it->second.intermediateNodes.size() && 01079 pos < (intermediatePos+2) * maxChildren; ++pos ) 01080 { 01081 if( !it->second.intermediateNodes[pos].node.isUnspecified() && 01082 adoptResp->getChild() == it->second.intermediateNodes[pos].node ){ 01083 return; 01084 } 01085 } 01086 01087 // child is a "real" child->remove it from cache 01088 if( !it->second.cachedChildren.erase( adoptResp->getChild() ) ){ 01089 // if node got deleted in the meantime, inform parent... 01090 PubSubNodeLeftMessage* goneMsg = new PubSubNodeLeftMessage("Node left Subspace"); 01091 goneMsg->setNode( adoptResp->getChild() ); 01092 goneMsg->setSubspaceId( it->second.getId().getId() ); 01093 goneMsg->setBitLength( PUBSUB_NODELEFT_L( goneMsg )); 01094 RECORD_STATS( 01095 ++numPubSubSignalingMessages; 01096 pubSubSignalingMessagesSize+= goneMsg->getByteLength() 01097 ); 01098 sendMessageToUDP( adoptResp->getSrcNode(), goneMsg ); 01099 return; 01100 } 01101 01102 // move child to intermediate node's childrenlist 01103 if( !iit->children.insert( adoptResp->getChild() ).second ){ 01104 // Node was already in children list, fix children count 01105 subspace.fixTotalChildrenCount(); 01106 } 01107 iit->waitingChildren--; 01108 01109 // FIXME: just for testing 01110 PubSubSubspaceResponsible& subspace = it->second; 01111 int iii = subspace.getTotalChildrenCount(); 01112 subspace.fixTotalChildrenCount(); 01113 if( iii != subspace.getTotalChildrenCount() ){ 01114 opp_error("Huh?"); 01115 } 01116 01117 // Inform Backup 01118 if( !it->second.getBackupNode().isUnspecified() ){ 01119 PubSubBackupSubscriptionMessage* backupMsg = new PubSubBackupSubscriptionMessage("Backup: node got a new parent"); 01120 backupMsg->setSubspaceId( adoptResp->getSubspaceId() ); 01121 backupMsg->setChild( adoptResp->getChild() ); 01122 backupMsg->setParent( adoptResp->getSrcNode() ); 01123 backupMsg->setBitLength( PUBSUB_BACKUPSUBSCRIPTION_L( backupMsg )); 01124 RECORD_STATS( 01125 ++numPubSubSignalingMessages; 01126 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 01127 ); 01128 sendMessageToUDP( it->second.getBackupNode(), backupMsg ); 01129 return; 01130 } 01131 } 01132 } 01133 01134 EV << "[PubSubMMOG::handleAdoptChildResponse() @ " << thisNode.getAddress() 01135 << " (" << thisNode.getKey().toString(16) << ")]\n" 01136 << " Received AdoptChild Response for unknown child!\n" 01137 << endl; 01138 }
void PubSubMMOG::handleAppMessage | ( | cMessage * | msg | ) | [virtual] |
Processes "timer" self-messages.
msg | A self-message Processes non-commonAPI messages | |
msg | non-commonAPIMessage |
Reimplemented from BaseOverlay.
Definition at line 315 of file PubSubMMOG.cc.
00316 { 00317 if( GameAPIPositionMessage *posMsg = dynamic_cast<GameAPIPositionMessage*>(msg) ) { 00318 if( state == READY ) { 00319 handleMove( posMsg ); 00320 } else if ( state == JOINING ) { 00321 // We are not connected to our responsible node, inform app 00322 CompReadyMessage* msg = new CompReadyMessage("Overlay not READY!"); 00323 msg->setReady(false); 00324 msg->setComp(getThisCompType()); 00325 send( msg, "appOut"); 00326 } else if ( state == INIT ) { 00327 // This is only called for the first MOVE message 00328 // Trigger login 00329 PubSubJoinCall* joinMsg = new PubSubJoinCall("Login"); 00330 joinMsg->setPosition( posMsg->getPosition() ); 00331 // FIXME: Ressource handling not yet supported! 00332 joinMsg->setRessources( 4 ); 00333 sendUdpRpcCall( lobbyServer, joinMsg ); 00334 00335 state = JOINING; 00336 setBootstrapedIcon(); 00337 00338 // tell app to wait until login is confirmed... 00339 CompReadyMessage* readyMsg = new CompReadyMessage("Overlay not READY!"); 00340 readyMsg->setReady(false); 00341 readyMsg->setComp(getThisCompType()); 00342 send( readyMsg, "appOut"); 00343 00344 currentRegionX = (unsigned int) (posMsg->getPosition().x/subspaceSize); 00345 currentRegionY = (unsigned int) (posMsg->getPosition().y/subspaceSize); 00346 } 00347 delete msg; 00348 } 00349 }
void PubSubMMOG::handleBackupCall | ( | PubSubBackupCall * | backupCall | ) | [protected] |
Definition at line 799 of file PubSubMMOG.cc.
Referenced by handleRpcCall().
00800 { 00801 int intId = backupCall->getSubspaceId(); 00802 PubSubSubspaceId subspaceId(intId, numSubspaces); 00803 00804 // Start Heartbeat Timer 00805 PubSubTimer* parentTimeout = new PubSubTimer("ParentTimeout"); 00806 parentTimeout->setType( PUBSUB_PARENT_TIMEOUT ); 00807 parentTimeout->setSubspaceId( intId ); 00808 startTimer( parentTimeout ); 00809 00810 // insert subspace into responsible list 00811 PubSubSubspaceResponsible subspace( subspaceId ); 00812 subspace.setResponsibleNode( backupCall->getSrcNode() ); 00813 subspace.setHeartbeatTimer( parentTimeout ); 00814 00815 // recounstruct load balancing tree 00816 for( unsigned int i = 0; i < backupCall->getIntermediatesArraySize(); ++i ){ 00817 PubSubSubspaceResponsible::IntermediateNode iNode; 00818 iNode.node = backupCall->getIntermediates(i); 00819 subspace.intermediateNodes.push_back( iNode ); 00820 } 00821 for( unsigned int i = 0; i < backupCall->getChildrenArraySize(); ++i ){ 00822 int pos = backupCall->getChildrenPos( i ); 00823 if( pos == -2 ){ 00824 subspace.cachedChildren.insert( make_pair( backupCall->getChildren(i), false )); 00825 } else if( pos == -1 ){ 00826 subspace.children.insert( backupCall->getChildren(i) ); 00827 } else { 00828 subspace.intermediateNodes[pos].children.insert( backupCall->getChildren(i) ); 00829 } 00830 } 00831 00832 backupSubspaces.insert( make_pair(subspaceId, subspace) ); 00833 00834 PubSubBackupResponse* backupResp = new PubSubBackupResponse("I'll be your backup"); 00835 backupResp->setSubspaceId( intId ); 00836 backupResp->setBitLength( PUBSUB_BACKUPRESPONSE_L( backupResp )); 00837 RECORD_STATS( 00838 ++numPubSubSignalingMessages; 00839 pubSubSignalingMessagesSize+= backupResp->getByteLength() 00840 ); 00841 sendRpcResponse( backupCall, backupResp ); 00842 }
void PubSubMMOG::handleBackupCallTimeout | ( | PubSubBackupCall * | backupCall, | |
const TransportAddress & | oldNode | |||
) | [protected] |
Definition at line 1288 of file PubSubMMOG.cc.
Referenced by handleRpcTimeout().
01289 { 01290 // FIXME: cast oldNode to NodeHandle 01291 // Inform Lobbyserver over failed node 01292 PubSubFailedNodeMessage* failedNode = new PubSubFailedNodeMessage("Node failed"); 01293 failedNode->setFailedNode( oldNode ); 01294 failedNode->setBitLength( PUBSUB_FAILEDNODE_L( failedNode )); 01295 RECORD_STATS( 01296 ++numPubSubSignalingMessages; 01297 pubSubSignalingMessagesSize+= failedNode->getByteLength() 01298 ); 01299 sendMessageToUDP( lobbyServer, failedNode ); 01300 01301 // Request new Backup 01302 PubSubHelpCall* helpCall = new PubSubHelpCall("I need a backup node"); 01303 helpCall->setHelpType( PUBSUB_BACKUP ); 01304 helpCall->setSubspaceId( backupCall->getSubspaceId() ); 01305 helpCall->setBitLength( PUBSUB_HELPCALL_L( helpCall )); 01306 RECORD_STATS( 01307 ++numPubSubSignalingMessages; 01308 pubSubSignalingMessagesSize+= helpCall->getByteLength() 01309 ); 01310 sendUdpRpcCall( lobbyServer, helpCall ); 01311 01312 // find appropriate subspace and mark backup as failed 01313 PubSubSubspaceId subspaceId(backupCall->getSubspaceId(), numSubspaces); 01314 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01315 it = responsibleSubspaces.find( subspaceId ); 01316 if( it == responsibleSubspaces.end() ) { 01317 return; 01318 } 01319 it->second.setBackupNode( NodeHandle::UNSPECIFIED_NODE ); 01320 }
void PubSubMMOG::handleBackupResponse | ( | PubSubBackupResponse * | backupResp | ) | [protected] |
Definition at line 844 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
void PubSubMMOG::handleHelpResponse | ( | PubSubHelpResponse * | helpResp | ) | [protected] |
Definition at line 722 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
00723 { 00724 // lobby server answered our call for help 00725 // (i.e. he sends us a candidate for backup/intermediate nodes 00726 if( helpResp->getHelpType() == PUBSUB_BACKUP ){ 00727 PubSubBackupCall* backupCall = new PubSubBackupCall("Become my backup node!"); 00728 backupCall->setSubspaceId( helpResp->getSubspaceId() ); 00729 00730 // Find the subspace in the subspace map 00731 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 00732 it = responsibleSubspaces.find( PubSubSubspaceId(helpResp->getSubspaceId(), numSubspaces) ); 00733 if( it == responsibleSubspaces.end() ){ 00734 EV << "[PubSubMMOG::handleHelpResponse() @ " << thisNode.getAddress() 00735 << " (" << thisNode.getKey().toString(16) << ")]\n" 00736 << " received helpResponse for unknown subspace" << helpResp->getSubspaceId() << "\n" 00737 << endl; 00738 return; 00739 } 00740 PubSubSubspaceResponsible& subspace = it->second; 00741 00742 // Assume the new backup will not refuse his task 00743 subspace.setBackupNode( helpResp->getNode() ); 00744 00745 // FIXME: just for testing 00746 int iii = subspace.getTotalChildrenCount(); 00747 subspace.fixTotalChildrenCount(); 00748 if( iii != subspace.getTotalChildrenCount() ){ 00749 opp_error("Huh?"); 00750 } 00751 00752 // backup the load balancing tree 00753 backupCall->setChildrenArraySize( subspace.getTotalChildrenCount() ); 00754 backupCall->setChildrenPosArraySize( subspace.getTotalChildrenCount() ); 00755 backupCall->setIntermediatesArraySize( subspace.intermediateNodes.size() ); 00756 00757 set<NodeHandle>::iterator childIt; 00758 map<NodeHandle, bool>::iterator childMapIt; 00759 unsigned int i = 0; 00760 for( childMapIt = subspace.cachedChildren.begin(); childMapIt != subspace.cachedChildren.end(); ++childMapIt ){ 00761 backupCall->setChildren(i, childMapIt->first); 00762 backupCall->setChildrenPos(i, -2); 00763 ++i; 00764 } 00765 for( childIt = subspace.children.begin(); childIt != subspace.children.end(); ++childIt ){ 00766 backupCall->setChildren(i, *childIt); 00767 backupCall->setChildrenPos(i, -1); 00768 ++i; 00769 } 00770 for( unsigned int ii = 0; ii < subspace.intermediateNodes.size(); ++ii ){ 00771 PubSubSubspaceResponsible::IntermediateNode& iNode = subspace.intermediateNodes[ii]; 00772 backupCall->setIntermediates(ii, iNode.node); 00773 for( childIt = iNode.children.begin(); childIt != iNode.children.end(); ++childIt ){ 00774 backupCall->setChildren(i, *childIt); 00775 backupCall->setChildrenPos(i, ii); 00776 ++i; 00777 } 00778 } 00779 00780 backupCall->setBitLength( PUBSUB_BACKUPCALL_L( backupCall )); 00781 RECORD_STATS( 00782 ++numPubSubSignalingMessages; 00783 pubSubSignalingMessagesSize+= backupCall->getByteLength() 00784 ); 00785 sendUdpRpcCall( helpResp->getNode(), backupCall ); 00786 00787 } else if( helpResp->getHelpType() == PUBSUB_INTERMEDIATE ){ 00788 PubSubIntermediateCall* intermediateCall = new PubSubIntermediateCall("Become my intermediate node!"); 00789 intermediateCall->setSubspaceId( helpResp->getSubspaceId() ); 00790 intermediateCall->setBitLength( PUBSUB_INTERMEDIATECALL_L( intermediateCall )); 00791 RECORD_STATS( 00792 ++numPubSubSignalingMessages; 00793 pubSubSignalingMessagesSize+= intermediateCall->getByteLength() 00794 ); 00795 sendUdpRpcCall( helpResp->getNode(), intermediateCall ); 00796 } 00797 }
void PubSubMMOG::handleIntermediateBackup | ( | PubSubBackupIntermediateMessage * | backupMsg | ) | [protected] |
Definition at line 1512 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
01513 { 01514 // find appropriate subspace 01515 PubSubSubspaceId subspaceId(backupMsg->getSubspaceId(), numSubspaces); 01516 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01517 it = backupSubspaces.find( subspaceId ); 01518 if( it == backupSubspaces.end() ) { 01519 return; 01520 } 01521 01522 if( backupMsg->getPos() >= (int) it->second.intermediateNodes.size() ){ 01523 it->second.intermediateNodes.resize( backupMsg->getPos() + 1 ); 01524 } 01525 it->second.intermediateNodes[ backupMsg->getPos() ].node = backupMsg->getNode(); 01526 }
void PubSubMMOG::handleIntermediateCall | ( | PubSubIntermediateCall * | intermediateCall | ) | [protected] |
Definition at line 850 of file PubSubMMOG.cc.
Referenced by handleRpcCall().
00851 { 00852 // insert subspace into intermediate list 00853 PubSubSubspaceId subspaceId(intermediateCall->getSubspaceId(), numSubspaces); 00854 PubSubSubspaceIntermediate subspace( subspaceId ); 00855 subspace.setResponsibleNode( intermediateCall->getSrcNode() ); 00856 subspace.setTimestamp(0); 00857 intermediateSubspaces.insert( make_pair(subspaceId, subspace) ); 00858 00859 PubSubIntermediateResponse* iResp = new PubSubIntermediateResponse("I'll be your intermediate node"); 00860 iResp->setSubspaceId( intermediateCall->getSubspaceId() ); 00861 iResp->setBitLength( PUBSUB_INTERMEDIATERESPONSE_L( iResp )); 00862 RECORD_STATS( 00863 ++numPubSubSignalingMessages; 00864 pubSubSignalingMessagesSize+= iResp->getByteLength() 00865 ); 00866 sendRpcResponse( intermediateCall, iResp ); 00867 }
void PubSubMMOG::handleIntermediateResponse | ( | PubSubIntermediateResponse * | intermediateResp | ) | [protected] |
Definition at line 869 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
00870 { 00871 // we found a new intermediate node for a subspace 00872 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 00873 it = responsibleSubspaces.find( PubSubSubspaceId(intermediateResp->getSubspaceId(), numSubspaces) ); 00874 if( it == responsibleSubspaces.end() ) { 00875 EV << "[PubSubMMOG::handleIntermediateResponse() @ " << thisNode.getAddress() 00876 << " (" << thisNode.getKey().toString(16) << ")]\n" 00877 << " Received Intermediate Response for unknown Subspace!\n" 00878 << endl; 00879 return; 00880 } 00881 PubSubSubspaceResponsible& subspace = it->second; 00882 PubSubSubspaceResponsible::IntermediateNode iNode; 00883 iNode.node = intermediateResp->getSrcNode(); 00884 00885 // if there is any broken intermediate node in list, replace it 00886 bool newIntermediate = true; 00887 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 00888 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 00889 if( iit->node.isUnspecified() ){ 00890 iit->node = iNode.node; 00891 newIntermediate = false; 00892 break; 00893 } 00894 } 00895 if( iit == subspace.intermediateNodes.end() ){ 00896 subspace.intermediateNodes.push_back( iNode ); 00897 iit = subspace.intermediateNodes.end() - 1; 00898 } 00899 00900 // inform Backup 00901 if( !subspace.getBackupNode().isUnspecified() ){ 00902 PubSubBackupIntermediateMessage* backupMsg = new PubSubBackupIntermediateMessage("Backup: new Intermediate"); 00903 backupMsg->setSubspaceId( intermediateResp->getSubspaceId() ); 00904 backupMsg->setNode( iNode.node ); 00905 backupMsg->setPos( iit - subspace.intermediateNodes.begin() ); 00906 backupMsg->setBitLength( PUBSUB_BACKUPINTERMEDIATE_L( backupMsg )); 00907 RECORD_STATS( 00908 ++numPubSubSignalingMessages; 00909 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 00910 ); 00911 sendMessageToUDP( subspace.getBackupNode(), backupMsg ); 00912 } 00913 00914 // if needed, send adopt to parent 00915 int intermediatePos = iit - subspace.intermediateNodes.begin(); 00916 int parentPos = intermediatePos/maxChildren -1; 00917 if( parentPos >= 0 && !subspace.intermediateNodes[parentPos].node.isUnspecified() ){ 00918 PubSubAdoptChildCall* adoptCall = new PubSubAdoptChildCall("Adopt (intermediate) Node"); 00919 adoptCall->setSubspaceId( intermediateResp->getSubspaceId() ); 00920 adoptCall->setChild( iit->node ); 00921 adoptCall->setBitLength( PUBSUB_ADOPTCHILDCALL_L( adoptCall )); 00922 RECORD_STATS( 00923 ++numPubSubSignalingMessages; 00924 pubSubSignalingMessagesSize+= adoptCall->getByteLength() 00925 ); 00926 sendUdpRpcCall( subspace.intermediateNodes[parentPos].node, adoptCall ); 00927 } 00928 00929 if( newIntermediate ){ 00930 // move one child from iNodes's parent to cache 00931 if( parentPos >= 0 ) { 00932 // parent is an intermediate node 00933 PubSubSubspaceResponsible::IntermediateNode& parent = subspace.intermediateNodes[parentPos]; 00934 if( parent.children.begin() != parent.children.end() ){ 00935 bool fixNeeded = false; 00936 if( !subspace.cachedChildren.insert( make_pair( *(parent.children.begin()), false )).second ){ 00937 fixNeeded = true; 00938 } 00939 if( !subspace.getBackupNode().isUnspecified() ){ 00940 PubSubBackupSubscriptionMessage* backupMsg = new PubSubBackupSubscriptionMessage("Backup: nodes moved to cache"); 00941 backupMsg->setSubspaceId( intermediateResp->getSubspaceId() ); 00942 backupMsg->setChild( *(parent.children.begin()) ); 00943 backupMsg->setOldParent( parent.node ); 00944 backupMsg->setBitLength( PUBSUB_BACKUPSUBSCRIPTION_L( backupMsg )); 00945 RECORD_STATS( 00946 ++numPubSubSignalingMessages; 00947 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 00948 ); 00949 sendMessageToUDP( subspace.getBackupNode(), backupMsg ); 00950 } 00951 PubSubNodeLeftMessage* goneMsg = new PubSubNodeLeftMessage("Node left: moved"); 00952 goneMsg->setNode( *(parent.children.begin()) ); 00953 goneMsg->setSubspaceId( intermediateResp->getSubspaceId() ); 00954 goneMsg->setBitLength( PUBSUB_NODELEFT_L( goneMsg )); 00955 RECORD_STATS( 00956 ++numPubSubSignalingMessages; 00957 pubSubSignalingMessagesSize+= goneMsg->getByteLength() 00958 ); 00959 sendMessageToUDP( parent.node, goneMsg ); 00960 parent.children.erase( parent.children.begin() ); 00961 if( fixNeeded ){ 00962 subspace.fixTotalChildrenCount(); 00963 } 00964 } 00965 00966 } else { 00967 // we are parent 00968 if( subspace.children.begin() != subspace.children.end() ){ 00969 bool fixNeeded = false; 00970 if( !subspace.cachedChildren.insert( make_pair( *(subspace.children.begin()), false )).second ){ 00971 fixNeeded = true; 00972 } 00973 if( !subspace.getBackupNode().isUnspecified() ){ 00974 PubSubBackupSubscriptionMessage* backupMsg = new PubSubBackupSubscriptionMessage("Backup: nodes moved to cache"); 00975 backupMsg->setSubspaceId( intermediateResp->getSubspaceId() ); 00976 backupMsg->setChild( *(subspace.children.begin()) ); 00977 backupMsg->setOldParent( thisNode ); 00978 backupMsg->setBitLength( PUBSUB_BACKUPSUBSCRIPTION_L( backupMsg )); 00979 RECORD_STATS( 00980 ++numPubSubSignalingMessages; 00981 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 00982 ); 00983 sendMessageToUDP( subspace.getBackupNode(), backupMsg ); 00984 } 00985 subspace.children.erase( *(subspace.children.begin()) ); 00986 if( fixNeeded ){ 00987 subspace.fixTotalChildrenCount(); 00988 } 00989 } 00990 } 00991 } else { 00992 // send adopt for all children intermediates 00993 for( int pos = (intermediatePos+1) * maxChildren; pos < (int) subspace.intermediateNodes.size() && 00994 pos < (intermediatePos+2) * maxChildren; ++pos ){ 00995 if( subspace.intermediateNodes[pos].node.isUnspecified() ) continue; 00996 PubSubAdoptChildCall* adoptCall = new PubSubAdoptChildCall("Adopt (intermediate) Node"); 00997 adoptCall->setSubspaceId( intermediateResp->getSubspaceId() ); 00998 adoptCall->setChild( subspace.intermediateNodes[pos].node ); 00999 adoptCall->setBitLength( PUBSUB_ADOPTCHILDCALL_L( adoptCall )); 01000 RECORD_STATS( 01001 ++numPubSubSignalingMessages; 01002 pubSubSignalingMessagesSize+= adoptCall->getByteLength() 01003 ); 01004 sendUdpRpcCall( iit->node, adoptCall ); 01005 } 01006 } 01007 01008 // move as many cached children to the new node as possible 01009 std::map<NodeHandle,bool>::iterator childIt; 01010 for( childIt = subspace.cachedChildren.begin(); childIt != subspace.cachedChildren.end(); ++childIt ){ 01011 if( childIt->second ) continue; 01012 PubSubAdoptChildCall* adoptCall = new PubSubAdoptChildCall("Adopt Node"); 01013 adoptCall->setSubspaceId( intermediateResp->getSubspaceId() ); 01014 adoptCall->setChild( childIt->first ); 01015 adoptCall->setBitLength( PUBSUB_ADOPTCHILDCALL_L( adoptCall )); 01016 RECORD_STATS( 01017 ++numPubSubSignalingMessages; 01018 pubSubSignalingMessagesSize+= adoptCall->getByteLength() 01019 ); 01020 sendUdpRpcCall( intermediateResp->getSrcNode(), adoptCall ); 01021 childIt->second = true; 01022 if( (unsigned int) maxChildren == ++(iit->waitingChildren) ) break; 01023 } 01024 }
void PubSubMMOG::handleJoinResponse | ( | PubSubJoinResponse * | joinResp | ) | [protected] |
Definition at line 367 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
00368 { 00369 state = JOINING; 00370 setBootstrapedIcon(); 00371 PubSubSubspaceId region( currentRegionX, currentRegionY, numSubspaces); 00372 00373 NodeHandle respNode = joinResp->getResponsibleNode(); 00374 PubSubSubspace sub(region); 00375 sub.setResponsibleNode( respNode ); 00376 subscribedSubspaces.push_back( sub ); 00377 if( respNode.isUnspecified() ) { 00378 PubSubResponsibleNodeCall* respCall = new PubSubResponsibleNodeCall("Request Responsible NodeHandle"); 00379 respCall->setSubspacePos( Vector2D(currentRegionX, currentRegionY) ); 00380 respCall->setBitLength( PUBSUB_RESPONSIBLENODECALL_L( respCall ) ); 00381 RECORD_STATS( 00382 ++numPubSubSignalingMessages; 00383 pubSubSignalingMessagesSize+= respCall->getByteLength() 00384 ); 00385 sendUdpRpcCall( lobbyServer, respCall, NULL, 5, 5 ); // FIXME: Make it a parameter... 00386 } else { 00387 PubSubSubscriptionCall* subCall = new PubSubSubscriptionCall("JoinSubspace"); 00388 subCall->setSubspaceId( region.getId() ); 00389 subCall->setBitLength( PUBSUB_SUBSCRIPTIONCALL_L( subCall )); 00390 RECORD_STATS( 00391 ++numPubSubSignalingMessages; 00392 pubSubSignalingMessagesSize+= subCall->getByteLength() 00393 ); 00394 sendUdpRpcCall( respNode, subCall ); 00395 } 00396 }
void PubSubMMOG::handleMove | ( | GameAPIPositionMessage * | posMsg | ) | [protected] |
Definition at line 541 of file PubSubMMOG.cc.
Referenced by handleAppMessage().
00542 { 00543 currentRegionX = (unsigned int) (posMsg->getPosition().x/subspaceSize); 00544 currentRegionY = (unsigned int) (posMsg->getPosition().y/subspaceSize); 00545 00546 PubSubSubspaceId region( currentRegionX, currentRegionY, numSubspaces); 00547 00548 set<PubSubSubspaceId> expectedRegions; 00549 int minX = (int) ((posMsg->getPosition().x - AOIWidth)/subspaceSize); 00550 if( minX < 0 ) minX = 0; 00551 int maxX = (int) ((posMsg->getPosition().x + AOIWidth)/subspaceSize); 00552 if( maxX >= numSubspaces ) maxX = numSubspaces -1; 00553 int minY = (int) ((posMsg->getPosition().y - AOIWidth)/subspaceSize); 00554 if( minY < 0 ) minY = 0; 00555 int maxY = (int) ((posMsg->getPosition().y + AOIWidth)/subspaceSize); 00556 if( maxY >= numSubspaces ) maxY = numSubspaces -1; 00557 00558 // FIXME: make parameter: unsubscription size 00559 int minUnsubX = (int) ((posMsg->getPosition().x - 1.5*AOIWidth)/subspaceSize); 00560 if( minUnsubX < 0 ) minUnsubX = 0; 00561 int maxUnsubX = (int) ((posMsg->getPosition().x + 1.5*AOIWidth)/subspaceSize); 00562 if( maxUnsubX >= numSubspaces ) maxUnsubX = numSubspaces -1; 00563 int minUnsubY = (int) ((posMsg->getPosition().y - 1.5*AOIWidth)/subspaceSize); 00564 if( minUnsubY < 0 ) minUnsubY = 0; 00565 int maxUnsubY = (int) ((posMsg->getPosition().y + 1.5+AOIWidth)/subspaceSize); 00566 if( maxUnsubY >= numSubspaces ) maxUnsubY = numSubspaces -1; 00567 00568 for( int x = minX; x <= maxX; ++x ){ 00569 for( int y = minY; y <= maxY; ++y ){ 00570 expectedRegions.insert( PubSubSubspaceId( x, y, numSubspaces )); 00571 } 00572 } 00573 00574 list<PubSubSubspace>::iterator subIt = subscribedSubspaces.begin(); 00575 PubSubSubspace* subspace = NULL; 00576 while( subIt != subscribedSubspaces.end() ){ 00577 if( subIt->getId() == region ){ 00578 subspace = &*subIt; 00579 } 00580 expectedRegions.erase( subIt->getId() ); 00581 00582 // unsubscribe region if to far away 00583 if( subIt->getId().getX() < minX || subIt->getId().getX() > maxX || 00584 subIt->getId().getY() < minY || subIt->getId().getY() > maxY ){ 00585 if( !subIt->getResponsibleNode().isUnspecified() ){ 00586 PubSubUnsubscriptionMessage* unsubMsg = new PubSubUnsubscriptionMessage("Unsubscribe from subspace"); 00587 unsubMsg->setSubspaceId( subIt->getId().getId() ); 00588 unsubMsg->setSrc( thisNode ); 00589 unsubMsg->setBitLength( PUBSUB_UNSUBSCRIPTION_L( unsubMsg )); 00590 RECORD_STATS( 00591 ++numPubSubSignalingMessages; 00592 pubSubSignalingMessagesSize+= unsubMsg->getByteLength() 00593 ); 00594 sendMessageToUDP( subIt->getResponsibleNode(), unsubMsg ); 00595 } 00596 // Erase subspace from subscribedList and increase iterator 00597 subscribedSubspaces.erase( subIt++ ); 00598 } else { 00599 ++subIt; 00600 } 00601 } 00602 00603 // if any "near" region is not yet subscribed, subscribe 00604 for( set<PubSubSubspaceId>::iterator regionIt = expectedRegions.begin(); regionIt != expectedRegions.end(); ++regionIt ){ 00605 PubSubSubspace sub( *regionIt ); 00606 subscribedSubspaces.push_back( sub ); 00607 PubSubResponsibleNodeCall* respCall = new PubSubResponsibleNodeCall("Request Responsible NodeHandle"); 00608 respCall->setSubspacePos( Vector2D(regionIt->getX(), regionIt->getY()) ); 00609 respCall->setBitLength( PUBSUB_RESPONSIBLENODECALL_L( respCall )); 00610 RECORD_STATS( 00611 ++numPubSubSignalingMessages; 00612 pubSubSignalingMessagesSize+= respCall->getByteLength() 00613 ); 00614 sendUdpRpcCall( lobbyServer, respCall, NULL, 5, 5 ); // FIXME: Make it a parameter... 00615 } 00616 00617 if( subspace && !subspace->getResponsibleNode().isUnspecified() ){ 00618 PubSubMoveMessage* moveMsg = new PubSubMoveMessage("Player move"); 00619 moveMsg->setSubspaceId( region.getId() ); 00620 moveMsg->setPlayer( thisNode ); 00621 moveMsg->setPosition( posMsg->getPosition() ); 00622 moveMsg->setTimestamp( simTime() ); 00623 moveMsg->setBitLength( PUBSUB_MOVE_L( moveMsg )); 00624 RECORD_STATS( 00625 ++numMoveMessages; 00626 moveMessagesSize+= moveMsg->getByteLength() 00627 ); 00628 sendMessageToUDP( subspace->getResponsibleNode(), moveMsg ); 00629 } else { 00630 // trying to move to not-yet subscribed region 00631 // FIXME: change state to JOINING? 00632 } 00633 }
void PubSubMMOG::handleMoveListMessage | ( | PubSubMoveListMessage * | moveMsg | ) | [protected] |
Definition at line 666 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
00667 { 00668 simtime_t timestamp = moveMsg->getTimestamp(); 00669 00670 // If I'm intermediate node for this subspace, forward message to children 00671 std::map<PubSubSubspaceId, PubSubSubspaceIntermediate>::iterator it; 00672 it = intermediateSubspaces.find( PubSubSubspaceId(moveMsg->getSubspaceId(), numSubspaces) ); 00673 if( it != intermediateSubspaces.end() ){ 00674 // Forward only if the message has not already been forwarded 00675 if( it->second.getLastTimestamp() < moveMsg->getTimestamp() ){ 00676 set<NodeHandle>::iterator childIt; 00677 for( childIt = it->second.children.begin(); childIt != it->second.children.end(); ++childIt ){ 00678 sendMessageToUDP( *childIt, (BaseOverlayMessage*) moveMsg->dup() ); 00679 RECORD_STATS( 00680 ++numMoveListMessages; 00681 moveListMessagesSize+= moveMsg->getByteLength() 00682 ); 00683 } 00684 it->second.setTimestamp( timestamp ); 00685 } 00686 } 00687 00688 // If I'm subscribed to the subspace, transfer a GameAPIMoveList to app 00689 std::list<PubSubSubspace>::iterator subIt; 00690 for( subIt = subscribedSubspaces.begin(); subIt != subscribedSubspaces.end(); ++subIt ){ 00691 if( subIt->getId().getId() == moveMsg->getSubspaceId() ){ 00692 if( subIt->getLastTimestamp() < moveMsg->getTimestamp() ){ 00693 GameAPIListMessage* moveList = new GameAPIListMessage("player position update"); 00694 moveList->setCommand( NEIGHBOR_UPDATE ); 00695 moveList->setAddNeighborArraySize( moveMsg->getPlayerArraySize() ); 00696 moveList->setNeighborPositionArraySize( moveMsg->getPositionArraySize() ); 00697 for( unsigned int i = 0; i < moveMsg->getPlayerArraySize(); ++i ){ 00698 moveList->setAddNeighbor( i, moveMsg->getPlayer(i) ); 00699 moveList->setNeighborPosition( i, moveMsg->getPosition(i) ); 00700 RECORD_STATS( 00701 globalStatistics->addStdDev("PubSubMMOG: MoveDelay", 00702 SIMTIME_DBL(simTime() - timestamp + moveMsg->getPositionAge(i)) ); 00703 ); 00704 } 00705 send( moveList, "appOut" ); 00706 RECORD_STATS( 00707 if( timestamp < simTime() - maxMoveDelay ){ 00708 ++lostMovementLists; 00709 } else { 00710 ++receivedMovementLists; 00711 } 00712 if( subIt->getLastTimestamp() != 0) lostMovementLists += (int)(SIMTIME_DBL(timestamp - subIt->getLastTimestamp())*movementRate -1); 00713 00714 ); 00715 subIt->setTimestamp( timestamp ); 00716 } 00717 return; 00718 } 00719 } 00720 }
void PubSubMMOG::handleMoveMessage | ( | PubSubMoveMessage * | moveMsg | ) | [protected] |
Definition at line 635 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
00636 { 00637 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 00638 it = responsibleSubspaces.find( PubSubSubspaceId(moveMsg->getSubspaceId(), numSubspaces) ); 00639 if( it == responsibleSubspaces.end() ){ 00640 EV << "[PubSubMMOG::handleMoveMessage() @ " << thisNode.getAddress() 00641 << " (" << thisNode.getKey().toString(16) << ")]\n" 00642 << " received moveMessage for unknown subspace" << moveMsg->getSubspaceId() << "\n" 00643 << endl; 00644 return; 00645 } 00646 00647 // If message arrived in the correct timeslot, store move message until deadline 00648 // Note: This assumes, we get no messages with future timestamps. At least in 00649 // the simulation, this assumption will hold. 00650 // The allowOldMoveMessages parameter allows overriding the timeslot barriers and forward all 00651 // messages. 00652 if( allowOldMoveMessages || moveMsg->getTimestamp() >= eventDeliveryTimer->getArrivalTime() - 1.0/(2*movementRate) ){ 00653 it->second.waitingMoveMessages.push_back( moveMsg ); 00654 ++numEventsCorrectTimeslot; 00655 } else { 00656 EV << "[PubSubMMOG::handleMoveMessage() @ " << thisNode.getAddress() 00657 << " (" << thisNode.getKey().toString(16) << ")]\n" 00658 << " received moveMesage with Timestamp: " << moveMsg->getTimestamp() << "\n" 00659 << " deadline was: " << eventDeliveryTimer->getArrivalTime() - 1.0/(2*movementRate) << "\n" 00660 << endl; 00661 ++numEventsWrongTimeslot; 00662 cancelAndDelete( moveMsg ); 00663 } 00664 }
void PubSubMMOG::handleNodeLeftMessage | ( | PubSubNodeLeftMessage * | leftMsg | ) | [protected] |
Definition at line 432 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
00433 { 00434 std::map<PubSubSubspaceId, PubSubSubspaceIntermediate>::iterator it; 00435 it = intermediateSubspaces.find( PubSubSubspaceId(leftMsg->getSubspaceId(), numSubspaces) ); 00436 00437 if( it == intermediateSubspaces.end() ) return; 00438 00439 it->second.removeChild( leftMsg->getNode() ); 00440 }
void PubSubMMOG::handleParentTimeout | ( | PubSubTimer * | timer | ) | [protected] |
Definition at line 1260 of file PubSubMMOG.cc.
Referenced by handleTimerEvent().
01261 { 01262 // our parent timed out. we have to take over the subspace... 01263 PubSubSubspaceId subspaceId(timer->getSubspaceId(), numSubspaces); 01264 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01265 it = backupSubspaces.find( subspaceId ); 01266 if( it == backupSubspaces.end() ) { 01267 delete timer; 01268 return; 01269 } 01270 01271 // increase fail count; if to high, take over subspace 01272 it->second.incHeartbeatFailCount(); 01273 if( it->second.getHeartbeatFailCount() > 1 ) { // FIXME: make it a parameter 01274 01275 // Delete Timer 01276 cancelAndDelete( timer ); 01277 it->second.setHeartbeatTimer( NULL ); 01278 01279 // Take over Subspace 01280 takeOverSubspace( it->second ); 01281 backupSubspaces.erase( it ); 01282 01283 } else { 01284 startTimer( timer ); 01285 } 01286 }
void PubSubMMOG::handlePingCall | ( | PubSubPingCall * | hearbeatCall | ) | [protected] |
Definition at line 1140 of file PubSubMMOG.cc.
Referenced by handleRpcCall().
01141 { 01142 int subspaceId = pingCall->getSubspaceId(); 01143 01144 if( pingCall->getPingType() == PUBSUB_PING_BACKUP ){ 01145 // reset heartbeat timer 01146 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01147 it = backupSubspaces.find( PubSubSubspaceId(pingCall->getSubspaceId(), numSubspaces) ); 01148 if( it == backupSubspaces.end() ) { 01149 EV << "[PubSubMMOG::handlePingCall() @ " << thisNode.getAddress() 01150 << " (" << thisNode.getKey().toString(16) << ")]\n" 01151 << " Received PingCall for unknown Subspace!\n" 01152 << endl; 01153 // FIXME: Somebody thinks we are his backup. What shall we do? 01154 } else { 01155 it->second.resetHeartbeatFailCount(); 01156 startTimer( it->second.getHeartbeatTimer() ); 01157 } 01158 } 01159 01160 PubSubPingResponse* pingResp = new PubSubPingResponse("PingResponse"); 01161 pingResp->setSubspaceId( subspaceId ); 01162 pingResp->setBitLength( PUBSUB_PINGRESPONSE_L( pingResp )); 01163 RECORD_STATS( 01164 ++numPubSubSignalingMessages; 01165 pubSubSignalingMessagesSize+= pingResp->getByteLength() 01166 ); 01167 sendRpcResponse( pingCall, pingResp ); 01168 }
void PubSubMMOG::handlePingCallTimeout | ( | PubSubPingCall * | pingCall, | |
const TransportAddress & | oldNode | |||
) | [protected] |
Definition at line 1322 of file PubSubMMOG.cc.
Referenced by handleRpcTimeout().
01323 { 01324 // Inform Lobbyserver over failed node 01325 const NodeHandle& oldNodeHandle = dynamic_cast<const NodeHandle&>(oldNode); 01326 // FIXME: use oldNodeHandle instead of oldNode 01327 PubSubFailedNodeMessage* failedNode = new PubSubFailedNodeMessage("Node failed"); 01328 failedNode->setBitLength( PUBSUB_FAILEDNODE_L( failedNode )); 01329 RECORD_STATS( 01330 ++numPubSubSignalingMessages; 01331 pubSubSignalingMessagesSize+= failedNode->getByteLength() 01332 ); 01333 failedNode->setFailedNode( oldNode ); 01334 sendMessageToUDP( lobbyServer, failedNode ); 01335 01336 // find appropriate subspace 01337 PubSubSubspaceId subspaceId(pingCall->getSubspaceId(), numSubspaces); 01338 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01339 it = responsibleSubspaces.find( subspaceId ); 01340 if( it == responsibleSubspaces.end() ) { 01341 return; 01342 } 01343 PubSubSubspaceResponsible& subspace = it->second; 01344 01345 if( pingCall->getPingType() == PUBSUB_PING_CHILD ){ 01346 // remove child 01347 unsubscribeChild( oldNodeHandle, subspace ); 01348 01349 } else if( pingCall->getPingType() == PUBSUB_PING_BACKUP ){ 01350 01351 // if we didn't already have (or asked for) a new backup 01352 if( !subspace.getBackupNode().isUnspecified() && 01353 subspace.getBackupNode() == oldNodeHandle ) 01354 { 01355 // our backup timed out. we have to request a new one... 01356 // delete old backup entry 01357 subspace.setBackupNode( NodeHandle::UNSPECIFIED_NODE ); 01358 01359 // Request new Backup 01360 PubSubHelpCall* helpCall = new PubSubHelpCall("I need a backup node"); 01361 helpCall->setHelpType( PUBSUB_BACKUP ); 01362 helpCall->setSubspaceId( pingCall->getSubspaceId() ); 01363 helpCall->setBitLength( PUBSUB_HELPCALL_L( helpCall )); 01364 RECORD_STATS( 01365 ++numPubSubSignalingMessages; 01366 pubSubSignalingMessagesSize+= helpCall->getByteLength() 01367 ); 01368 sendUdpRpcCall( lobbyServer, helpCall ); 01369 } 01370 01371 } else if( pingCall->getPingType() == PUBSUB_PING_INTERMEDIATE ){ 01372 // one intermediate node timed out. we have to request a new one... 01373 // delete old intermediate entry 01374 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 01375 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 01376 if( !iit->node.isUnspecified() && oldNode == iit->node ) break; 01377 } 01378 if( iit == subspace.intermediateNodes.end() ) return; 01379 01380 NodeHandle oldNode = iit->node; 01381 iit->node = NodeHandle::UNSPECIFIED_NODE; 01382 01383 // inform Backup 01384 if( !subspace.getBackupNode().isUnspecified() ){ 01385 PubSubBackupIntermediateMessage* backupMsg = new PubSubBackupIntermediateMessage("Backup: Intermediate failed"); 01386 backupMsg->setSubspaceId( pingCall->getSubspaceId() ); 01387 backupMsg->setPos( iit - it->second.intermediateNodes.begin() ); 01388 backupMsg->setBitLength( PUBSUB_BACKUPINTERMEDIATE_L( backupMsg )); 01389 RECORD_STATS( 01390 ++numPubSubSignalingMessages; 01391 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 01392 ); 01393 sendMessageToUDP( subspace.getBackupNode(), backupMsg ); 01394 } 01395 01396 bool fixNeeded = false; 01397 // Take over all children until new intermediate is found. 01398 set<NodeHandle>::iterator childIt; 01399 for( childIt = iit->children.begin(); childIt != iit->children.end(); ++childIt ){ 01400 if( !subspace.cachedChildren.insert( make_pair(*childIt, false)).second ){ 01401 fixNeeded = true; 01402 } 01403 01404 // Inform Backup 01405 if( !subspace.getBackupNode().isUnspecified() ){ 01406 PubSubBackupSubscriptionMessage* backupMsg = new PubSubBackupSubscriptionMessage("Backup: nodes moved to cache"); 01407 backupMsg->setSubspaceId( pingCall->getSubspaceId() ); 01408 backupMsg->setChild( *childIt ); 01409 backupMsg->setOldParent( oldNodeHandle ); 01410 backupMsg->setBitLength( PUBSUB_BACKUPSUBSCRIPTION_L( backupMsg )); 01411 RECORD_STATS( 01412 ++numPubSubSignalingMessages; 01413 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 01414 ); 01415 sendMessageToUDP( subspace.getBackupNode(), backupMsg ); 01416 } 01417 } 01418 iit->children.clear(); 01419 if( fixNeeded ) subspace.fixTotalChildrenCount(); 01420 01421 // inform parent of intermediate node 01422 int parentPos = (iit - subspace.intermediateNodes.begin())/maxChildren -1; 01423 if( parentPos >= 0 ){ 01424 PubSubSubspaceResponsible::IntermediateNode& parent = subspace.intermediateNodes[parentPos]; 01425 if( !parent.node.isUnspecified() ){ 01426 PubSubNodeLeftMessage* goneMsg = new PubSubNodeLeftMessage("Intermediate left Subspace"); 01427 goneMsg->setNode( oldNodeHandle ); 01428 goneMsg->setSubspaceId( subspace.getId().getId() ); 01429 goneMsg->setBitLength( PUBSUB_NODELEFT_L( goneMsg )); 01430 RECORD_STATS( 01431 ++numPubSubSignalingMessages; 01432 pubSubSignalingMessagesSize+= goneMsg->getByteLength() 01433 ); 01434 sendMessageToUDP( parent.node, goneMsg ); 01435 } 01436 } 01437 01438 // Request new Intermediate 01439 PubSubHelpCall* helpCall = new PubSubHelpCall("I need an intermediate node"); 01440 helpCall->setHelpType( PUBSUB_INTERMEDIATE ); 01441 helpCall->setSubspaceId( pingCall->getSubspaceId() ); 01442 helpCall->setBitLength( PUBSUB_HELPCALL_L( helpCall )); 01443 RECORD_STATS( 01444 ++numPubSubSignalingMessages; 01445 pubSubSignalingMessagesSize+= helpCall->getByteLength() 01446 ); 01447 sendUdpRpcCall( lobbyServer, helpCall ); 01448 } 01449 // FIXME: just for testing 01450 int iii = subspace.getTotalChildrenCount(); 01451 subspace.fixTotalChildrenCount(); 01452 if( iii != subspace.getTotalChildrenCount() ){ 01453 opp_error("Huh?"); 01454 } 01455 01456 }
void PubSubMMOG::handlePingResponse | ( | PubSubPingResponse * | pingResp | ) | [protected] |
void PubSubMMOG::handleReleaseIntermediate | ( | PubSubReleaseIntermediateMessage * | releaseMsg | ) | [protected] |
Definition at line 1506 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
01507 { 01508 PubSubSubspaceId subspaceId(releaseMsg->getSubspaceId(), numSubspaces); 01509 intermediateSubspaces.erase( subspaceId ); 01510 }
void PubSubMMOG::handleReplacementMessage | ( | PubSubReplacementMessage * | replaceMsg | ) | [protected] |
Definition at line 1484 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
01485 { 01486 PubSubSubspaceId subspaceId(replaceMsg->getSubspaceId(), numSubspaces); 01487 01488 // There's a new responsible node for a subspace 01489 // Replace the old one in the intermediateSubspaces map... 01490 std::map<PubSubSubspaceId, PubSubSubspaceIntermediate>::iterator it; 01491 it = intermediateSubspaces.find( subspaceId ); 01492 if( it != intermediateSubspaces.end() ) { 01493 it->second.setResponsibleNode( replaceMsg->getNewResponsibleNode() ); 01494 } 01495 01496 // ... and in the subsribed subspaces list 01497 std::list<PubSubSubspace>::iterator iit; 01498 for( iit = subscribedSubspaces.begin(); iit != subscribedSubspaces.end(); ++iit ){ 01499 if( iit->getId() == subspaceId ) { 01500 iit->setResponsibleNode( replaceMsg->getNewResponsibleNode() ); 01501 return; 01502 } 01503 } 01504 }
void PubSubMMOG::handleResponsibleNodeResponse | ( | PubSubResponsibleNodeResponse * | subResp | ) | [protected] |
Definition at line 398 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
00399 { 00400 int subspaceId = subResp->getSubspaceId(); 00401 NodeHandle respNode = subResp->getResponsibleNode(); 00402 00403 std::list<PubSubSubspace>::iterator it = subscribedSubspaces.begin(); 00404 while( it != subscribedSubspaces.end() ) { 00405 if( it->getId().getId() == subspaceId) break; 00406 ++it; 00407 } 00408 if( it != subscribedSubspaces.end() ) { 00409 it->setResponsibleNode( respNode ); 00410 00411 PubSubSubscriptionCall* subCall = new PubSubSubscriptionCall("JoinSubspace"); 00412 subCall->setSubspaceId( subspaceId ); 00413 subCall->setBitLength( PUBSUB_SUBSCRIPTIONCALL_L( subCall )); 00414 RECORD_STATS( 00415 ++numPubSubSignalingMessages; 00416 pubSubSignalingMessagesSize+= subCall->getByteLength() 00417 ); 00418 sendUdpRpcCall( respNode, subCall ); 00419 } 00420 }
bool PubSubMMOG::handleRpcCall | ( | BaseCallMessage * | msg | ) | [virtual] |
Processes Remote-Procedure-Call invocation messages.
This method should be overloaded when the overlay provides RPC functionality.
Reimplemented from BaseRpc.
Definition at line 103 of file PubSubMMOG.cc.
00104 { 00105 // delegate messages 00106 RPC_SWITCH_START( msg ) 00107 RPC_DELEGATE( PubSubSubscription, handleSubscriptionCall ); 00108 RPC_DELEGATE( PubSubTakeOverSubspace, handleTakeOver ); 00109 RPC_DELEGATE( PubSubBackup, handleBackupCall ); 00110 RPC_DELEGATE( PubSubIntermediate, handleIntermediateCall ); 00111 RPC_DELEGATE( PubSubAdoptChild, handleAdoptChildCall ); 00112 RPC_DELEGATE( PubSubPing, handlePingCall ); 00113 RPC_SWITCH_END( ) 00114 00115 return RPC_HANDLED; 00116 00117 }
void PubSubMMOG::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [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.
Definition at line 119 of file PubSubMMOG.cc.
00122 { 00123 RPC_SWITCH_START(msg); 00124 RPC_ON_RESPONSE( PubSubJoin ) { 00125 handleJoinResponse( _PubSubJoinResponse ); 00126 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00127 << " (" << thisNode.getKey().toString(16) << ")]\n" 00128 << " Received a PubSubJoin RPC Response: id=" << rpcId << "\n" 00129 << " msg=" << *_PubSubJoinResponse << " rtt=" << rtt 00130 << endl; 00131 break; 00132 } 00133 RPC_ON_RESPONSE( PubSubSubscription ) { 00134 handleSubscriptionResponse( _PubSubSubscriptionResponse ); 00135 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00136 << " (" << thisNode.getKey().toString(16) << ")]\n" 00137 << " Received a PubSubSubscription RPC Response: id=" << rpcId << "\n" 00138 << " msg=" << *_PubSubSubscriptionResponse << " rtt=" << rtt 00139 << endl; 00140 break; 00141 } 00142 RPC_ON_RESPONSE( PubSubResponsibleNode ) { 00143 handleResponsibleNodeResponse( _PubSubResponsibleNodeResponse ); 00144 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00145 << " (" << thisNode.getKey().toString(16) << ")]\n" 00146 << " Received a PubSubResponsibleNode RPC Response: id=" << rpcId << "\n" 00147 << " msg=" << *_PubSubResponsibleNodeResponse << " rtt=" << rtt 00148 << endl; 00149 break; 00150 } 00151 RPC_ON_RESPONSE( PubSubHelp ) { 00152 handleHelpResponse( _PubSubHelpResponse ); 00153 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00154 << " (" << thisNode.getKey().toString(16) << ")]\n" 00155 << " Received a PubSubHelp RPC Response: id=" << rpcId << "\n" 00156 << " msg=" << *_PubSubHelpResponse << " rtt=" << rtt 00157 << endl; 00158 break; 00159 } 00160 RPC_ON_RESPONSE( PubSubBackup ) { 00161 handleBackupResponse( _PubSubBackupResponse ); 00162 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00163 << " (" << thisNode.getKey().toString(16) << ")]\n" 00164 << " Received a PubSubBackup RPC Response: id=" << rpcId << "\n" 00165 << " msg=" << *_PubSubBackupResponse << " rtt=" << rtt 00166 << endl; 00167 break; 00168 } 00169 RPC_ON_RESPONSE( PubSubIntermediate ) { 00170 handleIntermediateResponse( _PubSubIntermediateResponse ); 00171 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00172 << " (" << thisNode.getKey().toString(16) << ")]\n" 00173 << " Received a PubSubIntermediate RPC Response: id=" << rpcId << "\n" 00174 << " msg=" << *_PubSubIntermediateResponse << " rtt=" << rtt 00175 << endl; 00176 break; 00177 } 00178 RPC_ON_RESPONSE( PubSubAdoptChild ) { 00179 handleAdoptChildResponse( _PubSubAdoptChildResponse ); 00180 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00181 << " (" << thisNode.getKey().toString(16) << ")]\n" 00182 << " Received a PubSubAdoptChild RPC Response: id=" << rpcId << "\n" 00183 << " msg=" << *_PubSubAdoptChildResponse << " rtt=" << rtt 00184 << endl; 00185 break; 00186 } 00187 RPC_ON_RESPONSE( PubSubPing ) { 00188 handlePingResponse( _PubSubPingResponse ); 00189 EV << "[PubSubMMOG::handleRpcResponse() @ " << thisNode.getAddress() 00190 << " (" << thisNode.getKey().toString(16) << ")]\n" 00191 << " Received a PubSubPing RPC Response: id=" << rpcId << "\n" 00192 << " msg=" << *_PubSubPingResponse << " rtt=" << rtt 00193 << endl; 00194 break; 00195 } 00196 RPC_SWITCH_END( ); 00197 }
void PubSubMMOG::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
cPolymorphic * | context, | |||
int | rpcId, | |||
const OverlayKey & | destKey | |||
) | [virtual] |
This method is called if an RPC timeout has been reached.
msg | The original RPC message. | |
dest | The destination node | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
destKey | the destination OverlayKey |
Reimplemented from RpcListener.
Definition at line 199 of file PubSubMMOG.cc.
00203 { 00204 RPC_SWITCH_START(msg) 00205 RPC_ON_CALL( PubSubBackup ) { 00206 handleBackupCallTimeout( _PubSubBackupCall, dest ); 00207 EV << "[PubSubMMOG::handleRpcTimeout() @ " << thisNode.getAddress() 00208 << " (" << thisNode.getKey().toString(16) << ")]\n" 00209 << " Backup RPC Call timed out: id=" << rpcId << "\n" 00210 << " msg=" << *_PubSubBackupCall 00211 << " oldNode=" << dest 00212 << endl; 00213 break; 00214 } 00215 RPC_ON_CALL( PubSubPing ) { 00216 handlePingCallTimeout( _PubSubPingCall, dest ); 00217 EV << "[PubSubMMOG::handleRpcTimeout() @ " << thisNode.getAddress() 00218 << " (" << thisNode.getKey().toString(16) << ")]\n" 00219 << " Ping RPC Call timed out: id=" << rpcId << "\n" 00220 << " msg=" << *_PubSubPingCall 00221 << " oldNode=" << dest 00222 << endl; 00223 break; 00224 } 00225 RPC_ON_CALL( PubSubSubscription ) { 00226 handleSubscriptionCallTimeout( _PubSubSubscriptionCall, dest ); 00227 EV << "[PubSubMMOG::handleRpcTimeout() @ " << thisNode.getAddress() 00228 << " (" << thisNode.getKey().toString(16) << ")]\n" 00229 << " Subscription RPC Call timed out: id=" << rpcId << "\n" 00230 << " msg=" << *_PubSubSubscriptionCall 00231 << " oldNode=" << dest 00232 << endl; 00233 break; 00234 } 00235 RPC_SWITCH_END( ) 00236 00237 // FIXME: 00238 // AdoptCall missing! 00239 // IntermediateCall missing! 00240 // (ResponsibleNodeCall missing) 00241 // (HelpCall missing) 00242 }
void PubSubMMOG::handleSubscriptionBackup | ( | PubSubBackupSubscriptionMessage * | backupMsg | ) | [protected] |
Definition at line 1528 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
01529 { 01530 // Note: this funktion may break subspace's tatalChildrenCall 01531 // You have to use fixTotalChildrenCount before using the subspace 01532 // find appropriate subspace 01533 PubSubSubspaceId subspaceId(backupMsg->getSubspaceId(), numSubspaces); 01534 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01535 it = backupSubspaces.find( subspaceId ); 01536 if( it == backupSubspaces.end() ) { 01537 return; 01538 } 01539 PubSubSubspaceResponsible& subspace = it->second; 01540 01541 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 01542 01543 if( !backupMsg->getOldParent().isUnspecified() ){ 01544 // oldParent set -> move child 01545 if( backupMsg->getOldParent() == subspace.getResponsibleNode() ){ 01546 // direct child -> cache 01547 subspace.removeChild( backupMsg->getChild() ); 01548 subspace.cachedChildren.insert(make_pair( backupMsg->getChild(), false) ); 01549 01550 } else { 01551 // from I -> chache 01552 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 01553 // if( !iit->node.isUnspecified() && iit->node == backupMsg->getOldParent() ){ 01554 iit->children.erase( backupMsg->getChild() ); 01555 // } 01556 } 01557 subspace.cachedChildren.insert(make_pair( backupMsg->getChild(), false) ); 01558 } 01559 } else if( backupMsg->getParent().isUnspecified() ){ 01560 // parent not set -> new child to chache 01561 subspace.cachedChildren.insert(make_pair( backupMsg->getChild(), false) ); 01562 01563 } else if( backupMsg->getParent() == subspace.getResponsibleNode() ){ 01564 // new direct child 01565 subspace.addChild( backupMsg->getChild() ); 01566 } else { 01567 // move child from cache to intermediate 01568 subspace.cachedChildren.erase( backupMsg->getChild() ); 01569 01570 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 01571 if( !iit->node.isUnspecified() && iit->node == backupMsg->getParent() ){ 01572 iit->children.insert( backupMsg->getChild() ); 01573 } 01574 } 01575 // FIXME: check for errors 01576 } 01577 }
void PubSubMMOG::handleSubscriptionCall | ( | PubSubSubscriptionCall * | subCall | ) | [protected] |
Definition at line 442 of file PubSubMMOG.cc.
Referenced by handleRpcCall().
00443 { 00444 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 00445 it = responsibleSubspaces.find( PubSubSubspaceId(subCall->getSubspaceId(), numSubspaces) ); 00446 00447 PubSubBackupSubscriptionMessage* backupMsg = 0; 00448 PubSubSubscriptionResponse* resp; 00449 if( it == responsibleSubspaces.end() ) { 00450 resp = new PubSubSubscriptionResponse("Subscription failed"); 00451 resp->setFailed( true ); 00452 } else { 00453 resp = new PubSubSubscriptionResponse("Subscription successful"); 00454 backupMsg = new PubSubBackupSubscriptionMessage("Backup: new subscription"); 00455 backupMsg->setSubspaceId( subCall->getSubspaceId() ); 00456 backupMsg->setChild( subCall->getSrcNode() ); 00457 00458 if( it->second.addChild( subCall->getSrcNode() )) { 00459 // We have still room for the child 00460 backupMsg->setParent( thisNode ); 00461 } else { 00462 // Child has to go to an intermediate node... 00463 if( PubSubSubspaceResponsible::IntermediateNode* iNode = it->second.getNextFreeIntermediate() ){ 00464 // find intermediate node with free slots 00465 PubSubAdoptChildCall* adoptCall = new PubSubAdoptChildCall("Adopt child"); 00466 adoptCall->setChild( subCall->getSrcNode() ); 00467 adoptCall->setSubspaceId( subCall->getSubspaceId() ); 00468 adoptCall->setBitLength( PUBSUB_ADOPTCHILDCALL_L( adoptCall )); 00469 sendUdpRpcCall( iNode->node, adoptCall ); 00470 RECORD_STATS( 00471 ++numPubSubSignalingMessages; 00472 pubSubSignalingMessagesSize+= adoptCall->getByteLength() 00473 ); 00474 iNode->waitingChildren++; 00475 } else { 00476 // no free slots available, create new intermediate node 00477 // FIXME: when getting two subscriptions at once, we're requesting too many intermediates 00478 PubSubHelpCall* helpCall = new PubSubHelpCall("I need an intermediate node"); 00479 helpCall->setHelpType( PUBSUB_INTERMEDIATE ); 00480 helpCall->setSubspaceId( subCall->getSubspaceId() ); 00481 helpCall->setBitLength( PUBSUB_HELPCALL_L( helpCall )); 00482 sendUdpRpcCall( lobbyServer, helpCall ); 00483 RECORD_STATS( 00484 ++numPubSubSignalingMessages; 00485 pubSubSignalingMessagesSize+= helpCall->getByteLength() 00486 ); 00487 } 00488 } 00489 } 00490 resp->setBitLength( PUBSUB_SUBSCRIPTIONRESPONSE_L( resp )); 00491 sendRpcResponse( subCall, resp ); 00492 RECORD_STATS( 00493 ++numPubSubSignalingMessages; 00494 pubSubSignalingMessagesSize+= resp->getByteLength() 00495 ); 00496 00497 if( it == responsibleSubspaces.end() ) return; 00498 00499 // FIXME: just for testing 00500 PubSubSubspaceResponsible& subspace = it->second; 00501 int iii = subspace.getTotalChildrenCount(); 00502 subspace.fixTotalChildrenCount(); 00503 if( iii != subspace.getTotalChildrenCount() ){ 00504 opp_error("Huh?"); 00505 } 00506 00507 if( !it->second.getBackupNode().isUnspecified() ){ 00508 backupMsg->setBitLength( PUBSUB_BACKUPSUBSCRIPTION_L( backupMsg )); 00509 RECORD_STATS( 00510 ++numPubSubSignalingMessages; 00511 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 00512 ); 00513 sendMessageToUDP( it->second.getBackupNode(), backupMsg ); 00514 } else { 00515 delete backupMsg; 00516 } 00517 }
void PubSubMMOG::handleSubscriptionCallTimeout | ( | PubSubSubscriptionCall * | subscriptionCall, | |
const TransportAddress & | oldNode | |||
) | [protected] |
Definition at line 1458 of file PubSubMMOG.cc.
Referenced by handleRpcTimeout().
01459 { 01460 // FIXME: cast oldNode to NodeHandle 01461 // our subscription call timed out. This means the responsible node is dead... 01462 // Inform Lobbyserver over failed node 01463 PubSubFailedNodeMessage* failedNode = new PubSubFailedNodeMessage("Node failed"); 01464 failedNode->setFailedNode( oldNode ); 01465 failedNode->setBitLength( PUBSUB_FAILEDNODE_L( failedNode )); 01466 RECORD_STATS( 01467 ++numPubSubSignalingMessages; 01468 pubSubSignalingMessagesSize+= failedNode->getByteLength() 01469 ); 01470 sendMessageToUDP( lobbyServer, failedNode ); 01471 01472 // Ask for new responsible node 01473 PubSubResponsibleNodeCall* respCall = new PubSubResponsibleNodeCall("Request Responsible NodeHandle"); 01474 PubSubSubspaceId subspaceId( subscriptionCall->getSubspaceId(), numSubspaces); 01475 respCall->setSubspacePos( Vector2D(subspaceId.getX(), subspaceId.getY()) ); 01476 respCall->setBitLength( PUBSUB_RESPONSIBLENODECALL_L( respCall )); 01477 RECORD_STATS( 01478 ++numPubSubSignalingMessages; 01479 pubSubSignalingMessagesSize+= respCall->getByteLength() 01480 ); 01481 sendUdpRpcCall( lobbyServer, respCall, NULL, 5, 5 ); // FIXME: Make it a parameter... 01482 }
void PubSubMMOG::handleSubscriptionResponse | ( | PubSubSubscriptionResponse * | subResp | ) | [protected] |
Definition at line 351 of file PubSubMMOG.cc.
Referenced by handleRpcResponse().
00352 { 00353 if( subResp->getFailed() ) { 00354 // TODO: get new resp node... 00355 } else { 00356 if( state != READY ){ 00357 state = READY; 00358 setBootstrapedIcon(); 00359 CompReadyMessage* readyMsg = new CompReadyMessage("Overlay READY!"); 00360 readyMsg->setReady(true); 00361 readyMsg->setComp(getThisCompType()); 00362 sendDelayed( readyMsg, ceil(simTime()) - simTime(), "appOut" ); 00363 } 00364 } 00365 }
void PubSubMMOG::handleTakeOver | ( | PubSubTakeOverSubspaceCall * | toCall | ) | [protected] |
Definition at line 519 of file PubSubMMOG.cc.
Referenced by handleRpcCall().
00520 { 00521 PubSubSubspaceId region((int) toCall->getSubspacePos().x, (int) toCall->getSubspacePos().y, numSubspaces); 00522 00523 takeOverNewSubspace( region ); 00524 00525 PubSubTakeOverSubspaceResponse* toResp = new PubSubTakeOverSubspaceResponse("Accept subspace responsibility"); 00526 toResp->setSubspacePos( toCall->getSubspacePos() ); 00527 toResp->setBitLength( PUBSUB_TAKEOVERSUBSPACERESPONSE_L( toResp )); 00528 RECORD_STATS( 00529 ++numPubSubSignalingMessages; 00530 pubSubSignalingMessagesSize+= toResp->getByteLength() 00531 ); 00532 sendRpcResponse( toCall, toResp ); 00533 }
void PubSubMMOG::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Reimplemented from BaseRpc.
Definition at line 275 of file PubSubMMOG.cc.
00276 { 00277 if( PubSubTimer* timer = dynamic_cast<PubSubTimer*>(msg) ) { 00278 switch( timer->getType() ) { 00279 case PUBSUB_HEARTBEAT: 00280 sendHearbeatToChildren(); 00281 startTimer( timer ); 00282 break; 00283 case PUBSUB_CHILDPING: 00284 sendPingToChildren(); 00285 startTimer( timer ); 00286 break; 00287 case PUBSUB_PARENT_TIMEOUT: 00288 handleParentTimeout( timer ); 00289 break; 00290 case PUBSUB_EVENTDELIVERY: 00291 publishEvents(); 00292 startTimer( timer ); 00293 break; 00294 } 00295 } else if( msg == joinTimer ) { 00296 // send a fake ready message to app to get initial position 00297 // Note: This is not consistent to the paper, where the lobby server 00298 // positions player. But it is needed for consistency with other MMOG protocols 00299 CompReadyMessage* msg = new CompReadyMessage("fake READY"); 00300 msg->setReady(true); 00301 msg->setComp(getThisCompType()); 00302 send( msg, "appOut"); 00303 delete joinTimer; 00304 joinTimer = NULL; 00305 // send initial AOI size to the application 00306 // Note: This is not consistent to the paper. 00307 // But it is needed for this nodes movement generation within the application layer. 00308 GameAPIResizeAOIMessage* gameMsg = new GameAPIResizeAOIMessage("RESIZE_AOI"); 00309 gameMsg->setCommand(RESIZE_AOI); 00310 gameMsg->setAOIsize(AOIWidth); 00311 send( gameMsg, "appOut"); 00312 } 00313 }
void PubSubMMOG::handleUDPMessage | ( | BaseOverlayMessage * | msg | ) | [virtual] |
Processes messages from underlay.
msg | Message from UDP |
Reimplemented from BaseOverlay.
Definition at line 244 of file PubSubMMOG.cc.
00245 { 00246 if( PubSubMoveListMessage* moveMsg = dynamic_cast<PubSubMoveListMessage*>(msg) ){ 00247 handleMoveListMessage( moveMsg ); 00248 delete moveMsg; 00249 } else if( PubSubMoveMessage* moveMsg = dynamic_cast<PubSubMoveMessage*>(msg) ){ 00250 handleMoveMessage( moveMsg ); 00251 } else if( PubSubUnsubscriptionMessage* unsMsg = dynamic_cast<PubSubUnsubscriptionMessage*>(msg) ){ 00252 handleUnsubscriptionMessage( unsMsg ); 00253 delete unsMsg; 00254 } else if( PubSubNodeLeftMessage* leftMsg = dynamic_cast<PubSubNodeLeftMessage*>(msg) ){ 00255 handleNodeLeftMessage( leftMsg ); 00256 delete leftMsg; 00257 } else if( PubSubReplacementMessage* replaceMsg = dynamic_cast<PubSubReplacementMessage*>(msg) ){ 00258 handleReplacementMessage( replaceMsg ); 00259 delete replaceMsg; 00260 } else if( PubSubBackupSubscriptionMessage* backupMsg = dynamic_cast<PubSubBackupSubscriptionMessage*>(msg) ){ 00261 handleSubscriptionBackup( backupMsg ); 00262 delete backupMsg; 00263 } else if( PubSubBackupUnsubscribeMessage* backupMsg = dynamic_cast<PubSubBackupUnsubscribeMessage*>(msg) ){ 00264 handleUnsubscribeBackup( backupMsg ); 00265 delete backupMsg; 00266 } else if( PubSubBackupIntermediateMessage* backupMsg = dynamic_cast<PubSubBackupIntermediateMessage*>(msg) ){ 00267 handleIntermediateBackup( backupMsg ); 00268 delete backupMsg; 00269 } else if( PubSubReleaseIntermediateMessage* releaseMsg = dynamic_cast<PubSubReleaseIntermediateMessage*>(msg) ){ 00270 handleReleaseIntermediate( releaseMsg ); 00271 delete releaseMsg; 00272 } 00273 }
void PubSubMMOG::handleUnsubscribeBackup | ( | PubSubBackupUnsubscribeMessage * | backupMsg | ) | [protected] |
Definition at line 1579 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
01580 { 01581 // Note: this funktion may break subspace's tatalChildrenCall 01582 // You have to use fixTotalChildrenCount before using the subspace 01583 // find appropriate subspace 01584 PubSubSubspaceId subspaceId(backupMsg->getSubspaceId(), numSubspaces); 01585 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01586 it = backupSubspaces.find( subspaceId ); 01587 if( it == backupSubspaces.end() ) { 01588 return; 01589 } 01590 PubSubSubspaceResponsible& subspace = it->second; 01591 01592 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 01593 set<NodeHandle>::iterator childIt; 01594 01595 if( !subspace.removeChild(backupMsg->getChild()) && !subspace.cachedChildren.erase( backupMsg->getChild()) ){ 01596 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 01597 iit->children.erase( backupMsg->getChild() ); 01598 } 01599 } 01600 if( !backupMsg->getIntermediate().isUnspecified() ){ 01601 // remove intermediate 01602 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 01603 if( !iit->node.isUnspecified() && iit->node == backupMsg->getIntermediate() ){ 01604 for( childIt = iit->children.begin(); childIt != iit->children.end(); ++childIt ){ 01605 // FIXME: note really stable. let the resp node inform us about child moves 01606 // remove children of last intermediate 01607 if( subspace.getNumChildren() + subspace.getNumIntermediates() < maxChildren ){ 01608 // we have room for the child 01609 subspace.children.insert( *childIt ); 01610 } else { 01611 // Node has to go to some intermediate 01612 // cache it 01613 subspace.cachedChildren.insert( make_pair(*childIt, true) ); 01614 } 01615 } 01616 subspace.intermediateNodes.erase( iit ); 01617 break; 01618 } 01619 } 01620 } 01621 }
void PubSubMMOG::handleUnsubscriptionMessage | ( | PubSubUnsubscriptionMessage * | unsMsg | ) | [protected] |
Definition at line 422 of file PubSubMMOG.cc.
Referenced by handleUDPMessage().
00423 { 00424 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 00425 it = responsibleSubspaces.find( PubSubSubspaceId(unsMsg->getSubspaceId(), numSubspaces) ); 00426 00427 if( it != responsibleSubspaces.end() ) { 00428 unsubscribeChild( unsMsg->getSrc(), it->second ); 00429 } 00430 }
void PubSubMMOG::initializeOverlay | ( | int | stage | ) | [virtual] |
Initializes derived-class-attributes.
Initializes derived-class-attributes, called by BaseOverlay::initialize(). By default this method is called once. If more stages are needed one can overload numInitStages() and add more stages.
stage | the init stage |
Reimplemented from BaseOverlay.
Definition at line 36 of file PubSubMMOG.cc.
00037 { 00038 // because of IPAddressResolver, we need to wait until interfaces are registered, 00039 // address auto-assignment takes place etc. 00040 if(stage != MIN_STAGE_OVERLAY) return; 00041 00042 state = INIT; 00043 setBootstrapedIcon(); 00044 // TODO: use BootstrapList instead (but this currently preferes 00045 // nodes from the same partition) 00046 lobbyServer = globalNodeList->getBootstrapNode(); 00047 00048 joinTimer = new cMessage("join timer"); 00049 simtime_t joinTime = ceil(simTime() + (simtime_t) par("joinDelay")); 00050 scheduleAt( joinTime, joinTimer ); 00051 00052 movementRate = par("movementRate"); 00053 eventDeliveryTimer = new PubSubTimer("event delivery timer"); 00054 eventDeliveryTimer->setType( PUBSUB_EVENTDELIVERY ); 00055 scheduleAt( joinTime + 1.0/(2*movementRate), eventDeliveryTimer ); 00056 00057 numSubspaces = par("numSubspaces"); 00058 subspaceSize = (int) ( (unsigned int) par("areaDimension") / numSubspaces); 00059 thisNode.setKey( OverlayKey::random() ); 00060 00061 maxChildren = par("maxChildren"); 00062 PubSubSubspaceResponsible::maxChildren = maxChildren; 00063 00064 AOIWidth = par("AOIWidth"); 00065 maxMoveDelay = par("maxMoveDelay"); 00066 00067 parentTimeout = par("parentTimeout"); 00068 heartbeatTimer = new PubSubTimer("HeartbeatTimer"); 00069 heartbeatTimer->setType( PUBSUB_HEARTBEAT ); 00070 startTimer( heartbeatTimer ); 00071 childPingTimer = new PubSubTimer("ChildPingTimer"); 00072 childPingTimer->setType( PUBSUB_CHILDPING ); 00073 startTimer( childPingTimer ); 00074 00075 allowOldMoveMessages = par("allowOldMoveMessages"); 00076 00077 numEventsWrongTimeslot = numEventsCorrectTimeslot = 0; 00078 numPubSubSignalingMessages = 0; 00079 pubSubSignalingMessagesSize = 0; 00080 numMoveMessages = 0; 00081 moveMessagesSize = 0; 00082 numMoveListMessages = 0; 00083 moveListMessagesSize = 0; 00084 respMoveListMessagesSize = 0; 00085 lostMovementLists = 0; 00086 receivedMovementLists = 0; 00087 WATCH( numPubSubSignalingMessages ); 00088 WATCH( pubSubSignalingMessagesSize ); 00089 WATCH( numMoveMessages ); 00090 WATCH( moveMessagesSize ); 00091 WATCH( numMoveListMessages ); 00092 WATCH( moveListMessagesSize ); 00093 WATCH( numEventsWrongTimeslot ); 00094 WATCH( numEventsCorrectTimeslot ); 00095 WATCH( lostMovementLists ); 00096 WATCH( receivedMovementLists ); 00097 WATCH_LIST( subscribedSubspaces ); 00098 WATCH_MAP( responsibleSubspaces ); 00099 WATCH_MAP( backupSubspaces ); 00100 WATCH_MAP( intermediateSubspaces ); 00101 }
void PubSubMMOG::publishEvents | ( | ) | [protected] |
Definition at line 1851 of file PubSubMMOG.cc.
Referenced by handleTimerEvent().
01852 { 01853 // FOr all (responsible) subspaces 01854 int numRespSubspaces = responsibleSubspaces.size(); 01855 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01856 for( it = responsibleSubspaces.begin(); it != responsibleSubspaces.end(); ++it ){ 01857 PubSubSubspaceResponsible& subspace = it->second; 01858 01859 // Prepare a movement list message aggregating all stored move messages 01860 PubSubMoveListMessage* moveList = new PubSubMoveListMessage("Movement list"); 01861 moveList->setTimestamp( simTime() ); 01862 moveList->setSubspaceId( subspace.getId().getId() ); 01863 moveList->setPlayerArraySize( subspace.waitingMoveMessages.size() ); 01864 moveList->setPositionArraySize( subspace.waitingMoveMessages.size() ); 01865 moveList->setPositionAgeArraySize( subspace.waitingMoveMessages.size() ); 01866 01867 std::deque<PubSubMoveMessage*>::iterator msgIt; 01868 int pos = 0; 01869 for( msgIt = subspace.waitingMoveMessages.begin(); msgIt != subspace.waitingMoveMessages.end(); ++msgIt ){ 01870 moveList->setPlayer( pos, (*msgIt)->getPlayer() ); 01871 moveList->setPosition( pos, (*msgIt)->getPosition() ); 01872 moveList->setPositionAge( pos, simTime() - (*msgIt)->getCreationTime() ); 01873 pos++; 01874 cancelAndDelete( *msgIt ); 01875 } 01876 subspace.waitingMoveMessages.clear(); 01877 01878 moveList->setBitLength( PUBSUB_MOVELIST_L( moveList )); 01879 // Send message to all direct children... 01880 for( set<NodeHandle>::iterator childIt = subspace.children.begin(); 01881 childIt != subspace.children.end(); ++childIt ) 01882 { 01883 RECORD_STATS( 01884 ++numMoveListMessages; 01885 moveListMessagesSize+= moveList->getByteLength(); 01886 respMoveListMessagesSize+= (int)((double) moveList->getByteLength() / numRespSubspaces) 01887 ); 01888 sendMessageToUDP( *childIt, (BaseOverlayMessage*) moveList->dup() ); 01889 } 01890 01891 //... all cached children (if messages are not too big) ... 01892 if( moveList->getByteLength() < 1024 ){ // FIXME: magic number. make it a parameter, or dependant on the available bandwidth 01893 for( map<NodeHandle, bool>::iterator childIt = subspace.cachedChildren.begin(); 01894 childIt != subspace.cachedChildren.end(); ++childIt ) 01895 { 01896 RECORD_STATS( 01897 ++numMoveListMessages; 01898 moveListMessagesSize+= moveList->getByteLength(); 01899 respMoveListMessagesSize+= (int)((double) moveList->getByteLength() / numRespSubspaces) 01900 ); 01901 sendMessageToUDP( childIt->first, (BaseOverlayMessage*) moveList->dup() ); 01902 // ... but don't send msgs to too many cached children, as this would exhaust our bandwidth 01903 } 01904 } 01905 01906 // ... all direct intermediates and intermediates with broken parent 01907 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 01908 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ) 01909 { 01910 int intermediatePos = iit - subspace.intermediateNodes.begin(); 01911 if( intermediatePos >= maxChildren && 01912 !subspace.intermediateNodes[intermediatePos/maxChildren -1].node.isUnspecified() ) continue; 01913 if( !iit->node.isUnspecified() ) { 01914 RECORD_STATS( 01915 ++numMoveListMessages; 01916 moveListMessagesSize+= moveList->getByteLength(); 01917 respMoveListMessagesSize+= (int)((double) moveList->getByteLength() / numRespSubspaces) 01918 ); 01919 sendMessageToUDP( iit->node, (BaseOverlayMessage*) moveList->dup() ); 01920 } 01921 } 01922 01923 delete moveList; 01924 } 01925 }
void PubSubMMOG::receiveChangeNotification | ( | int | category, | |
const cPolymorphic * | details | |||
) | [virtual] |
callback-method for events at the NotificationBoard
category | ... TODO ... | |
details | ... TODO ... |
Reimplemented from BaseOverlay.
Definition at line 535 of file PubSubMMOG.cc.
void PubSubMMOG::sendHearbeatToChildren | ( | ) | [protected] |
Definition at line 1227 of file PubSubMMOG.cc.
Referenced by handleTimerEvent().
01228 { 01229 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01230 for( it = responsibleSubspaces.begin(); it != responsibleSubspaces.end(); ++it) { 01231 PubSubPingCall* bHeartbeat = new PubSubPingCall("Heartbeat Backup"); 01232 bHeartbeat->setPingType( PUBSUB_PING_BACKUP ); 01233 bHeartbeat->setSubspaceId( it->second.getId().getId() ); 01234 bHeartbeat->setBitLength( PUBSUB_PINGCALL_L( bHeartbeat )); 01235 01236 PubSubPingCall* iHeartbeat = new PubSubPingCall("Heartbeat Intermediate"); 01237 iHeartbeat->setPingType( PUBSUB_PING_INTERMEDIATE ); 01238 iHeartbeat->setSubspaceId( it->second.getId().getId() ); 01239 iHeartbeat->setBitLength( PUBSUB_PINGCALL_L( iHeartbeat )); 01240 01241 sendMessageToChildren( it->second, iHeartbeat, bHeartbeat, NULL); 01242 delete bHeartbeat; 01243 delete iHeartbeat; 01244 } 01245 }
void PubSubMMOG::sendMessageToChildren | ( | PubSubSubspaceResponsible & | subspace, | |
BaseOverlayMessage * | toIntermediates, | |||
BaseOverlayMessage * | toBackup, | |||
BaseOverlayMessage * | toPlayers | |||
) | [protected] |
Definition at line 1749 of file PubSubMMOG.cc.
Referenced by sendHearbeatToChildren(), sendPingToChildren(), and takeOverSubspace().
01753 { 01754 BaseCallMessage* intermediateCall = dynamic_cast<BaseCallMessage*>(toIntermediates); 01755 BaseCallMessage* backupCall = dynamic_cast<BaseCallMessage*>(toBackup); 01756 BaseCallMessage* playerCall = dynamic_cast<BaseCallMessage*>(toPlayers); 01757 01758 std::set<NodeHandle>::iterator childIt; 01759 01760 if( toPlayers ) { 01761 // Inform all children ... 01762 for( childIt = subspace.children.begin(); childIt != subspace.children.end(); ++childIt ) { 01763 if( playerCall ){ 01764 RECORD_STATS( 01765 ++numPubSubSignalingMessages; 01766 pubSubSignalingMessagesSize+= playerCall->getByteLength() 01767 ); 01768 sendUdpRpcCall( *childIt, static_cast<BaseCallMessage*>(playerCall->dup()) ); 01769 } else { 01770 RECORD_STATS( 01771 ++numPubSubSignalingMessages; 01772 pubSubSignalingMessagesSize+= toPlayers->getByteLength() 01773 ); 01774 sendMessageToUDP( *childIt, static_cast<BaseOverlayMessage*>(toPlayers->dup()) ); 01775 } 01776 } 01777 // ... and all cached children ... 01778 std::map<NodeHandle, bool>::iterator cacheChildIt; 01779 for( cacheChildIt = subspace.cachedChildren.begin(); cacheChildIt != subspace.cachedChildren.end(); ++cacheChildIt ) { 01780 if( playerCall ){ 01781 RECORD_STATS( 01782 ++numPubSubSignalingMessages; 01783 pubSubSignalingMessagesSize+= playerCall->getByteLength() 01784 ); 01785 sendUdpRpcCall( cacheChildIt->first, static_cast<BaseCallMessage*>(playerCall->dup()) ); 01786 } else { 01787 RECORD_STATS( 01788 ++numPubSubSignalingMessages; 01789 pubSubSignalingMessagesSize+= toPlayers->getByteLength() 01790 ); 01791 sendMessageToUDP( cacheChildIt->first, static_cast<BaseOverlayMessage*>(toPlayers->dup()) ); 01792 } 01793 } 01794 } 01795 deque<PubSubSubspaceResponsible::IntermediateNode>::iterator iit; 01796 // ... all intermediate nodes ... 01797 for( iit = subspace.intermediateNodes.begin(); iit != subspace.intermediateNodes.end(); ++iit ){ 01798 if( toIntermediates && !iit->node.isUnspecified() ){ 01799 if( intermediateCall ){ 01800 RECORD_STATS( 01801 ++numPubSubSignalingMessages; 01802 pubSubSignalingMessagesSize+= intermediateCall->getByteLength() 01803 ); 01804 sendUdpRpcCall( iit->node, static_cast<BaseCallMessage*>(intermediateCall->dup()) ); 01805 } else { 01806 RECORD_STATS( 01807 ++numPubSubSignalingMessages; 01808 pubSubSignalingMessagesSize+= toIntermediates->getByteLength() 01809 ); 01810 sendMessageToUDP( iit->node, static_cast<BaseOverlayMessage*>(toIntermediates->dup()) ); 01811 } 01812 } 01813 if( toPlayers ) { 01814 // .. and all intermediate node's children ... 01815 for( childIt = iit->children.begin(); childIt != iit->children.end(); ++childIt ){ 01816 if( playerCall ){ 01817 RECORD_STATS( 01818 ++numPubSubSignalingMessages; 01819 pubSubSignalingMessagesSize+= playerCall->getByteLength() 01820 ); 01821 sendUdpRpcCall( *childIt, static_cast<BaseCallMessage*>(playerCall->dup()) ); 01822 } else { 01823 RECORD_STATS( 01824 ++numPubSubSignalingMessages; 01825 pubSubSignalingMessagesSize+= toPlayers->getByteLength() 01826 ); 01827 sendMessageToUDP( *childIt, static_cast<BaseOverlayMessage*>(toPlayers->dup()) ); 01828 } 01829 } 01830 } 01831 } 01832 // ... and the backup node 01833 if( toBackup && !subspace.getBackupNode().isUnspecified() ) { 01834 if( backupCall ){ 01835 RECORD_STATS( 01836 ++numPubSubSignalingMessages; 01837 pubSubSignalingMessagesSize+= backupCall->getByteLength() 01838 ); 01839 sendUdpRpcCall( subspace.getBackupNode(), static_cast<BaseCallMessage*>(backupCall->dup()) ); 01840 } else { 01841 RECORD_STATS( 01842 ++numPubSubSignalingMessages; 01843 pubSubSignalingMessagesSize+= toBackup->getByteLength() 01844 ); 01845 sendMessageToUDP( subspace.getBackupNode(), static_cast<BaseOverlayMessage*>(toBackup->dup()) ); 01846 } 01847 } 01848 }
void PubSubMMOG::sendPingToChildren | ( | ) | [protected] |
Definition at line 1247 of file PubSubMMOG.cc.
Referenced by handleTimerEvent().
01248 { 01249 std::map<PubSubSubspaceId, PubSubSubspaceResponsible>::iterator it; 01250 for( it = responsibleSubspaces.begin(); it != responsibleSubspaces.end(); ++it) { 01251 PubSubPingCall* heartbeat = new PubSubPingCall("Ping"); 01252 heartbeat->setPingType( PUBSUB_PING_CHILD ); 01253 heartbeat->setSubspaceId( it->second.getId().getId() ); 01254 heartbeat->setBitLength( PUBSUB_PINGCALL_L( heartbeat )); 01255 sendMessageToChildren( it->second, NULL, NULL, heartbeat ); 01256 delete heartbeat; 01257 } 01258 }
void PubSubMMOG::setBootstrapedIcon | ( | ) | [protected] |
Definition at line 1927 of file PubSubMMOG.cc.
Referenced by handleAppMessage(), handleJoinResponse(), handleSubscriptionResponse(), and initializeOverlay().
01928 { 01929 if(ev.isGUI()) { 01930 if(state == READY) { 01931 getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, "green"); 01932 getDisplayString().setTagArg("i", 1, "green"); 01933 } 01934 else if(state == JOINING) { 01935 getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, "yellow"); 01936 getDisplayString().setTagArg("i", 1, "yellow"); 01937 } 01938 else { 01939 getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, "red"); 01940 getDisplayString().setTagArg("i", 1, "red"); 01941 } 01942 } 01943 }
void PubSubMMOG::startTimer | ( | PubSubTimer * | timer | ) | [protected] |
Definition at line 1945 of file PubSubMMOG.cc.
Referenced by handleBackupCall(), handleParentTimeout(), handlePingCall(), handleTimerEvent(), and initializeOverlay().
01946 { 01947 if( !timer ) { 01948 EV << "[PubSubMMOG::startTimer() @ " << thisNode.getAddress() 01949 << " (" << thisNode.getKey().toString(16) << ")]\n" 01950 << " WARNING! Trying to start NULL timer @ " << thisNode << "\n" 01951 << endl; 01952 return; 01953 } 01954 01955 if( timer->isScheduled() ) { 01956 cancelEvent( timer ); 01957 } 01958 01959 simtime_t duration = 0; 01960 switch( timer->getType() ) { 01961 case PUBSUB_HEARTBEAT: 01962 duration = parentTimeout/2; 01963 break; 01964 case PUBSUB_CHILDPING: 01965 duration = parentTimeout*10; // FIXME: make it a parameter 01966 break; 01967 case PUBSUB_PARENT_TIMEOUT: 01968 duration = parentTimeout; 01969 break; 01970 case PUBSUB_EVENTDELIVERY: 01971 duration = 1.0/movementRate; 01972 break; 01973 } 01974 scheduleAt(simTime() + duration, timer ); 01975 }
void PubSubMMOG::takeOverNewSubspace | ( | PubSubSubspaceId | subspaceId | ) | [protected] |
Definition at line 1174 of file PubSubMMOG.cc.
Referenced by handleTakeOver().
01175 { 01176 // create a new subspace 01177 PubSubSubspaceResponsible subspace( subspaceId ); 01178 takeOverSubspace( subspace, true ); 01179 }
void PubSubMMOG::takeOverSubspace | ( | PubSubSubspaceResponsible & | subspaceId, | |
bool | isNew = false | |||
) | [protected] |
Definition at line 1181 of file PubSubMMOG.cc.
Referenced by handleParentTimeout(), and takeOverNewSubspace().
01182 { 01183 const PubSubSubspaceId& subspaceId = subspace.getId(); 01184 int intId = subspaceId.getId(); 01185 01186 subspace.fixTotalChildrenCount(); 01187 01188 NodeHandle oldNode = subspace.getResponsibleNode(); 01189 01190 // insert subspace into responsible list 01191 subspace.setResponsibleNode( thisNode ); 01192 responsibleSubspaces.insert( make_pair(subspaceId, subspace) ); 01193 01194 // request backup 01195 PubSubHelpCall* helpCall = new PubSubHelpCall("I need a backup node"); 01196 helpCall->setHelpType( PUBSUB_BACKUP ); 01197 helpCall->setSubspaceId( intId ); 01198 helpCall->setBitLength( PUBSUB_HELPCALL_L( helpCall )); 01199 RECORD_STATS( 01200 ++numPubSubSignalingMessages; 01201 pubSubSignalingMessagesSize+= helpCall->getByteLength() 01202 ); 01203 sendUdpRpcCall( lobbyServer, helpCall ); 01204 01205 if( !isNew ) { 01206 PubSubReplacementMessage* repMsg = new PubSubReplacementMessage("I replaced the responsible node"); 01207 repMsg->setSubspaceId( intId ); 01208 repMsg->setNewResponsibleNode( thisNode ); 01209 repMsg->setBitLength( PUBSUB_REPLACEMENT_L( repMsg )); 01210 01211 // Inform children and lobbyserver about takeover 01212 sendMessageToChildren( subspace, repMsg, NULL, repMsg ); 01213 sendMessageToUDP( lobbyServer, repMsg ); 01214 01215 // inform lobby server over failed node 01216 PubSubFailedNodeMessage* failedNode = new PubSubFailedNodeMessage("Node failed"); 01217 failedNode->setFailedNode( oldNode ); 01218 failedNode->setBitLength( PUBSUB_FAILEDNODE_L( failedNode )); 01219 RECORD_STATS( 01220 ++numPubSubSignalingMessages; 01221 pubSubSignalingMessagesSize+= failedNode->getByteLength() 01222 ); 01223 sendMessageToUDP( lobbyServer, failedNode ); 01224 } 01225 }
void PubSubMMOG::unsubscribeChild | ( | const NodeHandle & | node, | |
PubSubSubspaceResponsible & | subspace | |||
) | [protected] |
Definition at line 1623 of file PubSubMMOG.cc.
Referenced by handlePingCallTimeout(), and handleUnsubscriptionMessage().
01624 { 01625 PubSubBackupUnsubscribeMessage* backupMsg = new PubSubBackupUnsubscribeMessage("Backup: node left subspace"); 01626 backupMsg->setChild( node ); 01627 backupMsg->setSubspaceId( subspace.getId().getId() ); 01628 PubSubSubspaceResponsible::IntermediateNode* iNode = subspace.removeAnyChild( node ); 01629 if( iNode && !iNode->node.isUnspecified() ) { 01630 // Node is handled by an intermediate node, inform him 01631 PubSubNodeLeftMessage* goneMsg = new PubSubNodeLeftMessage("Node left Subspace"); 01632 goneMsg->setNode( node ); 01633 goneMsg->setSubspaceId( subspace.getId().getId() ); 01634 goneMsg->setBitLength( PUBSUB_NODELEFT_L( goneMsg )); 01635 RECORD_STATS( 01636 ++numPubSubSignalingMessages; 01637 pubSubSignalingMessagesSize+= goneMsg->getByteLength() 01638 ); 01639 sendMessageToUDP( iNode->node, goneMsg ); 01640 } 01641 if ( subspace.getTotalChildrenCount() < ( maxChildren - 1) * subspace.getNumIntermediates()){// FIXME: parameter when to start cleanup? 01642 // Too many "free" slots, remove one intermediate node 01643 PubSubSubspaceResponsible::IntermediateNode& liNode = subspace.intermediateNodes.back(); 01644 if( !liNode.node.isUnspecified() ){ 01645 // Inform node + lobby about release from intermediate node status 01646 PubSubReleaseIntermediateMessage* releaseMsg = new PubSubReleaseIntermediateMessage("I don't need you anymore as intermediate"); 01647 releaseMsg->setSubspaceId( subspace.getId().getId() ); 01648 releaseMsg->setBitLength( PUBSUB_RELEASEINTERMEDIATE_L( releaseMsg )); 01649 RECORD_STATS( 01650 ++numPubSubSignalingMessages; 01651 pubSubSignalingMessagesSize+= releaseMsg->getByteLength() 01652 ); 01653 sendMessageToUDP( liNode.node, releaseMsg ); 01654 01655 PubSubHelpReleaseMessage* helpRMsg = new PubSubHelpReleaseMessage("node is not my intermediate anymore"); 01656 helpRMsg->setSubspaceId( subspace.getId().getId() ); 01657 helpRMsg->setNode( liNode.node ); 01658 helpRMsg->setBitLength( PUBSUB_HELPRELEASE_L( helpRMsg )); 01659 RECORD_STATS( 01660 ++numPubSubSignalingMessages; 01661 pubSubSignalingMessagesSize+= helpRMsg->getByteLength() 01662 ); 01663 sendMessageToUDP( lobbyServer, helpRMsg ); 01664 01665 // inform parent of intermediate node 01666 int parentPos = (subspace.intermediateNodes.size()-1)/maxChildren -1; 01667 if( parentPos >= 0 ){ 01668 PubSubSubspaceResponsible::IntermediateNode& parent = subspace.intermediateNodes[parentPos]; 01669 if( !parent.node.isUnspecified() ){ 01670 PubSubNodeLeftMessage* goneMsg = new PubSubNodeLeftMessage("Intermediate left Subspace"); 01671 goneMsg->setNode( liNode.node ); 01672 goneMsg->setSubspaceId( subspace.getId().getId() ); 01673 goneMsg->setBitLength( PUBSUB_NODELEFT_L( goneMsg )); 01674 RECORD_STATS( 01675 ++numPubSubSignalingMessages; 01676 pubSubSignalingMessagesSize+= goneMsg->getByteLength() 01677 ); 01678 sendMessageToUDP( parent.node, goneMsg ); 01679 } 01680 } 01681 } 01682 01683 bool fixNeeded = false; 01684 set<NodeHandle>::iterator childIt; 01685 for( childIt = liNode.children.begin(); childIt != liNode.children.end(); ++childIt ){ 01686 // remove children of last intermediate 01687 if( subspace.getNumChildren() + subspace.getNumIntermediates() < maxChildren ){ 01688 // we have room for the child 01689 if( !subspace.children.insert( *childIt ).second ) fixNeeded = true; 01690 01691 //FIXME: send backup new->toMe 01692 } else { 01693 // Node has to go to some intermediate 01694 // find intermediate with free capacities 01695 PubSubSubspaceResponsible::IntermediateNode* newINode; 01696 newINode = subspace.getNextFreeIntermediate(); 01697 01698 if( newINode && newINode->node != liNode.node ){ 01699 // cache it 01700 if( !subspace.cachedChildren.insert( make_pair(*childIt, true) ).second ) fixNeeded = true; 01701 //FIXME: send backup new->toCache 01702 01703 ++(newINode->waitingChildren); 01704 01705 // let him adopt the child 01706 PubSubAdoptChildCall* adoptCall = new PubSubAdoptChildCall("Adopt Node"); 01707 adoptCall->setSubspaceId( subspace.getId().getId() ); 01708 adoptCall->setChild( *childIt ); 01709 adoptCall->setBitLength( PUBSUB_ADOPTCHILDCALL_L( adoptCall )); 01710 RECORD_STATS( 01711 ++numPubSubSignalingMessages; 01712 pubSubSignalingMessagesSize+= adoptCall->getByteLength() 01713 ); 01714 sendUdpRpcCall( newINode->node, adoptCall ); 01715 } else { 01716 // no intermediate found 01717 // just move child to cache and wait for a new one 01718 if( !subspace.cachedChildren.insert( make_pair(*childIt, false) ).second ) fixNeeded = true; 01719 } 01720 } 01721 } 01722 // delete node from subspace's intermediate node list 01723 subspace.intermediateNodes.pop_back(); 01724 // inform backup about deleted intermediate 01725 backupMsg->setIntermediate( liNode.node ); 01726 01727 if( fixNeeded ) subspace.fixTotalChildrenCount(); 01728 } 01729 01730 // FIXME: just for testing 01731 int iii = subspace.getTotalChildrenCount(); 01732 subspace.fixTotalChildrenCount(); 01733 if( iii != subspace.getTotalChildrenCount() ){ 01734 opp_error("Huh?"); 01735 } 01736 01737 if( !subspace.getBackupNode().isUnspecified() ){ 01738 backupMsg->setBitLength( PUBSUB_BACKUPUNSUBSCRIBE_L( backupMsg )); 01739 RECORD_STATS( 01740 ++numPubSubSignalingMessages; 01741 pubSubSignalingMessagesSize+= backupMsg->getByteLength() 01742 ); 01743 sendMessageToUDP( subspace.getBackupNode(), backupMsg ); 01744 } else { 01745 delete backupMsg; 01746 } 01747 }
bool PubSubMMOG::allowOldMoveMessages [protected] |
Definition at line 111 of file PubSubMMOG.h.
Referenced by handleMoveMessage(), and initializeOverlay().
int PubSubMMOG::AOIWidth [protected] |
Definition at line 105 of file PubSubMMOG.h.
Referenced by handleMove(), handleTimerEvent(), and initializeOverlay().
std::map<PubSubSubspaceId, PubSubSubspaceResponsible> PubSubMMOG::backupSubspaces [protected] |
Definition at line 101 of file PubSubMMOG.h.
Referenced by handleBackupCall(), handleIntermediateBackup(), handleParentTimeout(), handlePingCall(), handleSubscriptionBackup(), handleUnsubscribeBackup(), and initializeOverlay().
PubSubTimer* PubSubMMOG::childPingTimer [protected] |
Definition at line 117 of file PubSubMMOG.h.
Referenced by initializeOverlay().
unsigned int PubSubMMOG::currentRegionX [protected] |
Definition at line 113 of file PubSubMMOG.h.
Referenced by handleAppMessage(), handleJoinResponse(), and handleMove().
unsigned int PubSubMMOG::currentRegionY [protected] |
Definition at line 113 of file PubSubMMOG.h.
Referenced by handleAppMessage(), handleJoinResponse(), and handleMove().
PubSubTimer* PubSubMMOG::eventDeliveryTimer [protected] |
Definition at line 118 of file PubSubMMOG.h.
Referenced by handleMoveMessage(), and initializeOverlay().
PubSubTimer* PubSubMMOG::heartbeatTimer [protected] |
Definition at line 116 of file PubSubMMOG.h.
Referenced by initializeOverlay(), and ~PubSubMMOG().
std::map<PubSubSubspaceId, PubSubSubspaceIntermediate> PubSubMMOG::intermediateSubspaces [protected] |
Definition at line 102 of file PubSubMMOG.h.
Referenced by handleAdoptChildCall(), handleIntermediateCall(), handleMoveListMessage(), handleNodeLeftMessage(), handleReleaseIntermediate(), handleReplacementMessage(), and initializeOverlay().
cMessage* PubSubMMOG::joinTimer [protected] |
Definition at line 119 of file PubSubMMOG.h.
Referenced by handleTimerEvent(), and initializeOverlay().
TransportAddress PubSubMMOG::lobbyServer [protected] |
Definition at line 120 of file PubSubMMOG.h.
Referenced by handleAppMessage(), handleBackupCallTimeout(), handleJoinResponse(), handleMove(), handlePingCallTimeout(), handleSubscriptionCall(), handleSubscriptionCallTimeout(), initializeOverlay(), takeOverSubspace(), and unsubscribeChild().
int PubSubMMOG::lostMovementLists [protected] |
Definition at line 132 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMoveListMessage(), and initializeOverlay().
int PubSubMMOG::maxChildren [protected] |
Definition at line 109 of file PubSubMMOG.h.
Referenced by handleAdoptChildResponse(), handleIntermediateResponse(), handlePingCallTimeout(), handleUnsubscribeBackup(), initializeOverlay(), publishEvents(), and unsubscribeChild().
int PubSubMMOG::maxMoveDelay [protected] |
Definition at line 115 of file PubSubMMOG.h.
Referenced by handleMoveListMessage(), and initializeOverlay().
int PubSubMMOG::moveListMessagesSize [protected] |
Definition at line 130 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMoveListMessage(), initializeOverlay(), and publishEvents().
int PubSubMMOG::movementRate [protected] |
Definition at line 114 of file PubSubMMOG.h.
Referenced by handleMoveListMessage(), handleMoveMessage(), initializeOverlay(), and startTimer().
int PubSubMMOG::moveMessagesSize [protected] |
Definition at line 128 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMove(), and initializeOverlay().
int PubSubMMOG::numEventsCorrectTimeslot [protected] |
Definition at line 124 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMoveMessage(), and initializeOverlay().
int PubSubMMOG::numEventsWrongTimeslot [protected] |
Definition at line 123 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMoveMessage(), and initializeOverlay().
int PubSubMMOG::numMoveListMessages [protected] |
Definition at line 129 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMoveListMessage(), initializeOverlay(), and publishEvents().
int PubSubMMOG::numMoveMessages [protected] |
Definition at line 127 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMove(), and initializeOverlay().
int PubSubMMOG::numPubSubSignalingMessages [protected] |
Definition at line 125 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleAdoptChildCall(), handleAdoptChildResponse(), handleBackupCall(), handleBackupCallTimeout(), handleHelpResponse(), handleIntermediateCall(), handleIntermediateResponse(), handleJoinResponse(), handleMove(), handlePingCall(), handlePingCallTimeout(), handleResponsibleNodeResponse(), handleSubscriptionCall(), handleSubscriptionCallTimeout(), handleTakeOver(), initializeOverlay(), sendMessageToChildren(), takeOverSubspace(), and unsubscribeChild().
int PubSubMMOG::numSubspaces [protected] |
Definition at line 107 of file PubSubMMOG.h.
Referenced by handleAdoptChildCall(), handleAdoptChildResponse(), handleBackupCall(), handleBackupCallTimeout(), handleHelpResponse(), handleIntermediateBackup(), handleIntermediateCall(), handleIntermediateResponse(), handleJoinResponse(), handleMove(), handleMoveListMessage(), handleMoveMessage(), handleNodeLeftMessage(), handleParentTimeout(), handlePingCall(), handlePingCallTimeout(), handleReleaseIntermediate(), handleReplacementMessage(), handleSubscriptionBackup(), handleSubscriptionCall(), handleSubscriptionCallTimeout(), handleTakeOver(), handleUnsubscribeBackup(), handleUnsubscriptionMessage(), and initializeOverlay().
int PubSubMMOG::parentTimeout [protected] |
Definition at line 108 of file PubSubMMOG.h.
Referenced by handleBackupCall(), initializeOverlay(), and startTimer().
int PubSubMMOG::pubSubSignalingMessagesSize [protected] |
Definition at line 126 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleAdoptChildCall(), handleAdoptChildResponse(), handleBackupCall(), handleBackupCallTimeout(), handleHelpResponse(), handleIntermediateCall(), handleIntermediateResponse(), handleJoinResponse(), handleMove(), handlePingCall(), handlePingCallTimeout(), handleResponsibleNodeResponse(), handleSubscriptionCall(), handleSubscriptionCallTimeout(), handleTakeOver(), initializeOverlay(), sendMessageToChildren(), takeOverSubspace(), and unsubscribeChild().
int PubSubMMOG::receivedMovementLists [protected] |
Definition at line 133 of file PubSubMMOG.h.
Referenced by finishOverlay(), handleMoveListMessage(), and initializeOverlay().
int PubSubMMOG::respMoveListMessagesSize [protected] |
Definition at line 131 of file PubSubMMOG.h.
Referenced by finishOverlay(), initializeOverlay(), and publishEvents().
std::map<PubSubSubspaceId, PubSubSubspaceResponsible> PubSubMMOG::responsibleSubspaces [protected] |
Definition at line 100 of file PubSubMMOG.h.
Referenced by handleAdoptChildResponse(), handleBackupCallTimeout(), handleHelpResponse(), handleIntermediateResponse(), handleMoveMessage(), handlePingCallTimeout(), handleSubscriptionCall(), handleUnsubscriptionMessage(), initializeOverlay(), publishEvents(), sendHearbeatToChildren(), sendPingToChildren(), takeOverSubspace(), and ~PubSubMMOG().
std::list<PubSubSubspace> PubSubMMOG::subscribedSubspaces [protected] |
Definition at line 99 of file PubSubMMOG.h.
Referenced by handleJoinResponse(), handleMove(), handleMoveListMessage(), handleReplacementMessage(), handleResponsibleNodeResponse(), and initializeOverlay().
int PubSubMMOG::subspaceSize [protected] |
Definition at line 104 of file PubSubMMOG.h.
Referenced by handleAppMessage(), handleMove(), and initializeOverlay().