Commit 99c0ba35 by Aditya Bhatt

Merge branch 'manyclients-fix' into 'master'

Avoid choking/delays when connected to several clients

See merge request !1
parents 32e8b7af 57650fc3
......@@ -146,7 +146,8 @@ const unsigned int MAX_CONCURRENT_CONNECTIONS = 10;
bool Server::ServerCheck(EventQueue<MessageContainer> * queue, ROStime_t* now){
//fetch states of file descriptors using pselect
//cout << "connections" << *fdConnections.begin() << *fdConnections.end() << std::max(*fdConnections.end(), sL) <<endl;
//static int ctr = 0;
//poll for new connections:
struct sockaddr clientaddress;
socklen_t clientaddresslen = sizeof(clientaddress);
......@@ -166,11 +167,20 @@ const unsigned int MAX_CONCURRENT_CONNECTIONS = 10;
}
}
}
//scan through all open connections looking for data to read
ROStime_t duration_newpoll = GetNow() - *now;
// scan through all open connections looking for data to read
// Execution time: Each connected client takes ~4e6 nsecs on the beagle46, for the following loop
MessageContainer* message = new MessageContainer;
//int fd_iter = 0;
for (std::set<int>::iterator it_fd = fdConnections.begin(); it_fd != fdConnections.end();it_fd++) {
//int total_complete_messages = 0;
for (int msgcount = 0; msgcount < 100; msgcount++) { //execute at most 20 messages per timeslot and connection
int len = CheckForCompleteMessage(*it_fd, message->getData() );
//ROStime_t t_msg_init = GetNow();
int len = CheckForCompleteMessage(*it_fd, message->getData() ); // takes ~4300 nsecs on average
//ROStime_t t_msg_check = GetNow();
//cout << "msgcount: " << msgcount << ", " << "message->getData() duration: " << (t_msg_check-t_msg_init).nsecs << endl;
if(len == 0){
cout<<"Info: Connection "<<*it_fd<<" closed."<<endl;
if (this->sigSubMan != NULL)
......@@ -181,7 +191,20 @@ const unsigned int MAX_CONCURRENT_CONNECTIONS = 10;
fdConnections.erase(*it_fd);
continue;
}
if (len < 0) {continue;} //nothing to do
/*
* Explanation for the following line of code:
* 1. Usage statistics indicate that received messages tend to be consecutive in time.
* 2. So it is highly unlikely that polling for new messages 100 times in a single control tick will give us
* a sequence of messages with "gaps" in it. A typical streak of consecutive messages is about ~6 messages
* long during control, and ~42 messages long when establishing a new control connection.
* 3. Therefore, we need not finish the check for 100 messages, and can _break_ the polling loop during this
* control tick when, say, the 7th message check turns up blank. This saves a LOT of time and should
* technically allow us to have hundreds of connected clients.
* TODO: Lots of practical testing.
*/
if (len < 0) {break;} //nothing to do.
//total_complete_messages += 1;
//cout << "there's a message of length "<< std::dec << len << " in the buffer. Queueing it." <<endl;
//check whether time is really small, then assume a relative delta time from &now
ROStime_t* t = message->getTime();
......@@ -192,18 +215,34 @@ const unsigned int MAX_CONCURRENT_CONNECTIONS = 10;
ROStime_t delta = *now - *t;
cout << "WARNING: Received an Event for the past:"<< delta.secs + 0.000000001 * delta.nsecs << "s late (will be executed immediately)";
cout << endl;
}
}
message->sender_id = *it_fd; //record fd of the sender for replies (for subscriptions/connection based handling)
queue->push(*message);
ROStime_t duration = GetNow() - *now;
int duration_limit = (signed int)AirserverController::PERIOD_NS - 500000;
if (duration.nsecs > duration_limit) { //stop servicing messages and return
cout << "Exhausted time budget(" << duration_limit << "ns), postpone processing of network messages" <<std::endl;
cout << "Took " << duration.nsecs << "ns." <<std::endl;
delete message;
return true;
}
}
/*
if (total_complete_messages > 0) {
cout << "fd: " << fd_iter << ", total_complete_messages = " << total_complete_messages << endl;
}
fd_iter += 1;
*/
}
/*
ROStime_t duration_total = GetNow() - *now;
ctr += 1;
if (ctr % 1000 == 0) {
cout << "num connections: " << fdConnections.size() << endl;
cout << "Duration of ServerCheck: " << duration_total.nsecs << " (" << duration_newpoll.nsecs << " + " << (duration_total - duration_newpoll).nsecs << ")." << endl;
}*/
delete message;
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment