//if already failed, return 1. else return 0 int Membership::failMember(std::string ip_str, int timeStamp){ membersLock.lock(); bool exist = false; int position = 0; for(int i=0; i<members.size(); i++){ if( members[i].ip_str.compare( ip_str )==0 && members[i].timeStamp == timeStamp ){ exist = true; position = i; break; } } if(exist){ MemberUpdateMsg msg(MSG_LEAVE, members[position]); pushMsgToFileSysQueue(msg); members.erase( members.begin()+position ); } membersLock.unlock(); checkLeader(); return !exist; }
/*! * Selects or deselects the agent on the given slot. * \param agentNo * \param addToGroup True if agent is added to the selection. * \return True if agent has been selected or deselected. */ bool SquadSelection::selectAgent(size_t agentNo, bool addToGroup) { if (isAgentSelectable(agentNo)) { // saves the current selection to check if it changes size_t oldSelection = selected_agents_; if (addToGroup) { // Add/remove to the group selected_agents_ ^= 1 << agentNo; // check if leader was deselected checkLeader(agentNo); } else { selected_agents_ = 1 << agentNo; leader_ = agentNo; } return (oldSelection != selected_agents_); } return false; }
void Membership::detectThread() { /* WHILE LOOP roundId++ randomly select one node send ping message sleep(1) see msgQueue, search ack if(ack) cout<<alive sleep(4) continue send ping message to random K nodes (call spreadMessage()) sleep(4) see msgQueue, search ack if(ack) cout<<alive continue if(!ack) cout<<fail delete node send fail message to other nodes continue */ bool flagFail = false; Node failedNode; while(!killDetectingThread) { roundId = (roundId+1)%255; if (roundId % 5 == 0) { checkLeader(); } logFile<< std::endl << "Detection Thread - Round: "<< roundId << " ------------" << std::endl; logFile<<printMember(); if(members.size() < 2) { usleep(5 * MAX_LATENCY); flagFail = false; continue; } int select = rand()%(members.size()-1) + 1; Node theNode = members[select]; if (flagFail == true) { theNode = failedNode; } Message msg; msg.type = MSG_PING; msg.TTL = 0; msg.roundId = roundId; ipString2Char4(theNode.ip_str, msg.carrierAdd); msg.timeStamp = 0; logFile<<"detectThread: checking alive or not for "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl; sendUDP(sockfd, theNode.ip_str, port, (char*)&msg, sizeof(Message)); bool acked = false; if (queueSize() > 10){ std::cout << "Warning!!! queueSize = " << queueSize() << std::endl; } usleep(MAX_LATENCY); msgQueueLock.lock(); acked = ackMsgQueue(); msgQueueLock.unlock(); static int count = 0; if(acked){ logFile<<"detectThread: node alive: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl; flagFail = false; usleep(4 * MAX_LATENCY); continue; } logFile<<"Hey!!! Node "<<theNode.ip_str<<" did not respond the first time!" << std::endl; msg.type = MSG_PIGGY; msg.TTL = 0; spreadMessage(msg,3); usleep(4 * MAX_LATENCY); msgQueueLock.lock(); acked = ackMsgQueue(); msgQueueLock.unlock(); if(acked){ logFile<<"detectThread: second round found node alive: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl; flagFail = false; continue; } else{ logFile<< "detectThread: No ack received: node failed: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl; if (flagFail == true) { logFile<< "detectThread: No ack received: node failed: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl; failMember(theNode.ip_str, theNode.timeStamp); Message failMsg; failMsg.type = MSG_FAIL; failMsg.roundId = roundId; ipString2Char4(theNode.ip_str, failMsg.carrierAdd); failMsg.timeStamp = theNode.timeStamp; failMsg.TTL = 3; spreadMessage(failMsg); flagFail = false; } else { logFile<< "detectThread: Robust 2: It is alive: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl; failedNode = theNode; flagFail = true; } continue; } } }
/*! * Deselects an agent. Called when an agent died. * \param agentNo */ void SquadSelection::deselectAgent(size_t agentNo) { selected_agents_ &= ~(1 << agentNo); // check if leader was deselected checkLeader(agentNo); }