void MulticastPoint::handle_timeout(const boost::system::error_code& error) { if (!error) { //std::cout<<"timeout"<<std::endl; canWarn = true; //Re enable send error warnings KSystem::Time::TimeAbsolute now = KSystem::Time::SystemTime::now(); { //Clean old hosts first std::map<hostid, hostDescription>::iterator t, hit = otherHosts.begin(); KSystem::Time::TimeAbsolute oldest = now - KSystem::Time::TimeAbsolute::milliseconds(cleanupandbeacon * 4); while(hit != otherHosts.end()) { if((*hit).first == Messaging::MessageEntry::HOST_ID_ANY_HOST) //Do not cleanup ANYHOST { ++hit; continue; } if((*hit).second.lastseen < oldest) { //std::cout<<"Cleaning Host:"<<(*hit).first<<std::endl; t = hit++; otherHosts.erase(t); } else hit++; } cleanupLocalSubscriptions(); } { HostSubscriptions *hs = HostSubscriptions::default_instance().New(); hs->set_hostname(boost::asio::ip::host_name()); std::map<hostid, hostDescription>::const_iterator hit = otherHosts.begin(); for(; hit != otherHosts.end(); ++hit) { std::set<size_t>::const_iterator tit = (*hit).second.providesTopics.begin(); for(; tit != (*hit).second.providesTopics.end(); ++tit) { Subscription *s = hs->add_topics(); s->set_host((*hit).first); s->set_topicid(*tit); //std::cout<<"Requesting"<<(*hit).first<<" "<<(*tit)<<std::endl; } } Messaging::MessageEntry m; m.msg.reset(hs); m.topic = Messaging::Topics::Instance().getId("communication"); m.msgclass = Messaging::MessageEntry::STATE; m.timestamp = now.wrapTo<KSystem::Time::TimeStamp>(); m.host = Messaging::MessageEntry::HOST_ID_LOCAL_HOST; //std::cout<<"Beacon"<<std::endl; processOutGoing(m); } { //Internal message, forwarded to localhost, keeps track of known hosts, and this host info. KnownHosts *kn = KnownHosts::default_instance().New(); //Who am I? kn->mutable_localhost()->set_hostid(thishost); kn->mutable_localhost()->set_hostname(boost::asio::ip::host_name()); std::map<hostid, hostDescription>::const_iterator kit = otherHosts.begin(); for(; kit != otherHosts.end(); ++kit) { if((*kit).first == Messaging::MessageEntry::HOST_ID_ANY_HOST) //Do not report ANYHOST continue; HostEntry *e = kn->add_entrylist(); e->set_hostid((*kit).first); e->set_hostname((*kit).second.hostname); } Messaging::MessageEntry m; m.msg.reset(kn); m.topic = Messaging::Topics::Instance().getId("communication"); m.msgclass = Messaging::MessageEntry::STATE; m.timestamp = now.wrapTo<KSystem::Time::TimeStamp>(); m.host = Messaging::MessageEntry::HOST_ID_LOCAL_HOST; publish(m); } dep.cleanOlderThan(KSystem::Time::TimeAbsolute::milliseconds(cleanupandbeacon * 2)); timer_.expires_from_now(boost::posix_time::milliseconds(cleanupandbeacon)); timer_.async_wait( boost::bind(&MulticastPoint::handle_timeout, this, boost::asio::placeholders::error)); } }
void MulticastPoint::handle_timeout(const boost::system::error_code& error) { if (!error) { //std::cout<<"timeout"<<std::endl; canWarn = true; //Re enable send error warnings boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); { //Clean old hosts first std::map<hostid, hostDescription>::iterator t, hit = otherHosts.begin(); boost::posix_time::ptime oldest = now - boost::posix_time::milliseconds(cleanupandbeacon * 4); while(hit != otherHosts.end()) { if((*hit).first == msgentry::HOST_ID_ANY_HOST) //Do not cleanup ANYHOST { ++hit; continue; } if((*hit).second.lastseen < oldest) { //std::cout<<"Cleaning Host:"<<(*hit).first<<std::endl; t = hit++; otherHosts.erase(t); } else hit++; } std::set<size_t> remSub; std::set<size_t>::iterator sit; //Iterate all needed topics remSub = localsubscriptions; for( hit = otherHosts.begin(); hit != otherHosts.end(); hit++) for(sit = (*hit).second.needsTopics.begin(); sit != (*hit).second.needsTopics.end(); ++sit) remSub.erase(*sit); for(sit = remSub.begin(); sit != remSub.end(); ++sit) localsubscriptions.erase(*sit); std::vector<msgentry> newsubscriptions; msgentry kh; kh.msgclass = msgentry::UNSUBSCRIBE_ON_TOPIC; kh.host = msgentry::HOST_ID_LOCAL_HOST; for(sit = remSub.begin(); sit != remSub.end(); ++sit) { kh.topic = (*sit); newsubscriptions.push_back(kh); //std::cout<<"Unsubscribe from:"<<(*sit)<<std::endl; } publish(newsubscriptions); } { HostSubscriptions *hs = HostSubscriptions::default_instance().New(); hs->set_hostname(boost::asio::ip::host_name()); std::map<hostid, hostDescription>::const_iterator hit = otherHosts.begin(); for(; hit != otherHosts.end(); ++hit) { std::set<size_t>::const_iterator tit = (*hit).second.providesTopics.begin(); for(; tit != (*hit).second.providesTopics.end(); ++tit) { Subscription *s = hs->add_topics(); s->set_host((*hit).first); s->set_topicid(*tit); //std::cout<<"Requesting"<<(*hit).first<<" "<<(*tit)<<std::endl; } } msgentry m; m.msg.reset(hs); m.topic = Topics::Instance().getId("communication"); m.msgclass = msgentry::STATE; m.timestamp = now; m.host = msgentry::HOST_ID_LOCAL_HOST; //std::cout<<"Beacon"<<std::endl; processOutGoing(m); } { //Internal message, forwarded to localhost, keeps track of known hosts, and this host info. KnownHosts *kn = KnownHosts::default_instance().New(); //Who am I? kn->mutable_localhost()->set_hostid(thishost); kn->mutable_localhost()->set_hostname(boost::asio::ip::host_name()); std::map<hostid, hostDescription>::const_iterator kit = otherHosts.begin(); for(; kit != otherHosts.end(); ++kit) { if((*kit).first == msgentry::HOST_ID_ANY_HOST) //Do not report ANYHOST continue; HostEntry *e = kn->add_entrylist(); e->set_hostid((*kit).first); e->set_hostname((*kit).second.hostname); } msgentry m; m.msg.reset(kn); m.topic = Topics::Instance().getId("communication"); m.msgclass = msgentry::STATE; m.timestamp = now; m.host = msgentry::HOST_ID_LOCAL_HOST; publish(m); } dep.cleanOlderThan(boost::posix_time::milliseconds(cleanupandbeacon * 2)); timer_.expires_from_now(boost::posix_time::milliseconds(cleanupandbeacon)); timer_.async_wait( boost::bind(&MulticastPoint::handle_timeout, this, boost::asio::placeholders::error)); } }