diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-10-04 16:52:43 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-10-04 16:52:43 +0200 |
| commit | 6a0008b24344cbfb577c860f37f7d5cf74a311c1 (patch) | |
| tree | 2396932ed7d40a51ea7cf4243c5cee1ba8f2e395 | |
| parent | 720b5b3cebc7333c09ebe3ccfb1ae4184612c674 (diff) | |
| download | cmix-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.cpp | 52 |
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); } |
