I am using boost::asio::ip::udp::resolver in an SNMPV2 implementation to determine wheather a host is reachable or not.
using Resolver = boost::asio::ip::udp::resolver;
Resolver resolver(ioService);
Resolver::query query(connectOptions.getHost(),
connectOptions.getPort());
Resolver::iterator endpointIterator;
BOOST_LOG_SEV(logger, Severity::debug) << "Waiting for async resolve";
endpointIterator = resolver.async_resolve(query, yield);
BOOST_LOG_SEV(logger, Severity::debug) << "Async resolve done";
if (endpointIterator == Resolver::iterator{}) { // unreachable host
using namespace boost::system;
throw system_error{error_code{SnmpWrapperError::BadHostname}};
}
I have one test case where I test what is happening when a non existent hostname and an exitent hostname is queried paralell:
2013-09-16 10:45:28.687001: [DEBUG ] 0x88baf8 SnmpConnection: connect
2013-09-16 10:45:28.687396: [DEBUG ] 0x88baf8 SnmpConnection: host: non_existent_host_name_
2013-09-16 10:45:28.687434: [DEBUG ] 0x88baf8 SnmpConnection: port: 1611
2013-09-16 10:45:28.687456: [DEBUG ] 0x88baf8 SnmpConnection: Waiting for async resolve
2013-09-16 10:45:28.687675: [DEBUG ] 0x88c608 SnmpConnection: connect
2013-09-16 10:45:28.687853: [DEBUG ] 0x88c608 SnmpConnection: host: 127.0.0.1
2013-09-16 10:45:28.687883: [DEBUG ] 0x88c608 SnmpConnection: port: 1611
2013-09-16 10:45:28.687904: [DEBUG ] 0x88c608 SnmpConnection: Waiting for async resolve
2013-09-16 10:45:31.113527: [ERROR ] 0x88baf8 SnmpConnection: Host not found (authoritative)
2013-09-16 10:45:31.113708: [DEBUG ] 0x88c608 SnmpConnection: Async resolve done
2013-09-16 10:45:31.113738: [DEBUG ] 0x88c608 SnmpConnection: Connecting to 127.0.0.1:1611
...
From the logs it can be seen that the object with the reachable address is blocked until the other one's resolve is finished with the error (3 seconds). My assumption is that Asio resolver service uses one thread, so one query towards one unreachable host might block the processing of upcoming resolve requests.
Workaround would be to run the resolver service on more threads, is that possible? Or would it be possible to have a resolver service which works on sockets like the udp service does (instead of using ::getaddrinfo)?