aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-10-04 16:52:43 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-10-04 16:52:43 +0200
commit6a0008b24344cbfb577c860f37f7d5cf74a311c1 (patch)
tree2396932ed7d40a51ea7cf4243c5cee1ba8f2e395
parent720b5b3cebc7333c09ebe3ccfb1ae4184612c674 (diff)
downloadcmix-6a0008b24344cbfb577c860f37f7d5cf74a311c1.tar.gz
cmix-6a0008b24344cbfb577c860f37f7d5cf74a311c1.tar.bz2
cmix-6a0008b24344cbfb577c860f37f7d5cf74a311c1.zip
Retry connecting 5 times, 3, 6, 12, 24, 48 and 96 seconds between attempts
-rw-r--r--libcmix-network/connect.cpp52
1 files changed, 45 insertions, 7 deletions
diff --git a/libcmix-network/connect.cpp b/libcmix-network/connect.cpp
index f25ae24..6f1addf 100644
--- a/libcmix-network/connect.cpp
+++ b/libcmix-network/connect.cpp
@@ -29,21 +29,57 @@ boost::asio::ip::tcp::socket connect(std::string host, std::string port, io_serv
throw std::runtime_error("None of the supplied endpoints responded");
}
-void async_connect_iteration(tcp::socket& socket, boost::asio::ip::tcp::resolver::iterator it, std::function<void()> on_connect) {
- if(it == boost::asio::ip::tcp::resolver::iterator()) {
+struct IterationInfo {
+ int iteration;
+ boost::asio::ip::tcp::resolver::iterator it;
+ boost::asio::deadline_timer retry_timer;
+
+ IterationInfo(int iteration, boost::asio::ip::tcp::resolver::iterator it, boost::asio::io_service& io_service)
+ : iteration(iteration)
+ , it(it)
+ , retry_timer(io_service)
+ {}
+};
+
+void async_connect_iteration(tcp::socket& socket, std::shared_ptr<IterationInfo> info, std::function<void()> on_connect) {
+
+ if(info->it == boost::asio::ip::tcp::resolver::iterator()) {
throw std::runtime_error("None of the supplied endpoints responded");
}
- auto handler = [&socket, it, on_connect](boost::system::error_code const& ec) {
- if(ec) {
+ auto handler = [&socket, info, on_connect](boost::system::error_code const& ec) {
+ if(ec == boost::system::errc::connection_refused) {
+ socket.close();
+ if(info->iteration <= 5) {
+ int seconds_to_wait = std::pow(2, info->iteration) * 3;
+ info->iteration++;
+ BOOST_LOG_TRIVIAL(info) << "Connection refused, retrying in " << seconds_to_wait << " seconds.";
+
+ info->retry_timer.expires_from_now(boost::posix_time::seconds(seconds_to_wait));
+
+ info->retry_timer.async_wait([&socket, info, on_connect](boost::system::error_code const& ec){
+ if(ec) {
+ BOOST_LOG_TRIVIAL(error) << "Something went wrong with the retry timer: " << ec;
+ } else {
+ async_connect_iteration(socket, info, on_connect);
+ }
+ });
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "Connection was refused 5 times over the course of 189 seconds, moving to next resolved query";
+ info->it++;
+ info->iteration = 0;
+ async_connect_iteration(socket, info, on_connect);
+ }
+ } else if(ec) {
BOOST_LOG_TRIVIAL(info) << ec << std::endl;
- async_connect_iteration(socket, std::next(it), on_connect);
+ info->it++;
+ async_connect_iteration(socket, info, on_connect);
} else {
on_connect();
}
};
- socket.async_connect(*it, handler);
+ socket.async_connect(*(info->it), handler);
}
void async_connect(tcp::socket& socket, std::string host, std::string next_port, std::function<void()> on_connect)
@@ -53,5 +89,7 @@ void async_connect(tcp::socket& socket, std::string host, std::string next_port,
auto it = resolver.resolve(query);
- async_connect_iteration(socket, it, on_connect);
+ std::shared_ptr<IterationInfo> info = std::make_shared<IterationInfo>(0, it, socket.get_io_service());
+
+ async_connect_iteration(socket, info, on_connect);
}