changeset 591:b6101b01d0af

Irccd: bring back reconnection
author David Demelier <markand@malikania.fr>
date Tue, 05 Dec 2017 15:31:57 +0100
parents aec9e70d55ff
children 11532fdac611
files libirccd/irccd/server.cpp libirccd/irccd/server.hpp
diffstat 2 files changed, 35 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/libirccd/irccd/server.cpp	Tue Dec 05 14:54:45 2017 +0100
+++ b/libirccd/irccd/server.cpp	Tue Dec 05 15:31:57 2017 +0100
@@ -124,6 +124,7 @@
 server::server(boost::asio::io_service& service, std::string name)
     : name_(std::move(name))
     , service_(service)
+    , timer_(service)
 {
     // Initialize nickname and username.
     auto user = sys::username();
@@ -134,14 +135,6 @@
 
 void server::dispatch_connect(const irc::message&)
 {
-    recocur_ = 1;
-    jchannels_.clear();
-
-#if 0
-    timer_.start();
-#endif
-
-    // Change state and auto join requested channels.
     state_ = state_t::connected;
     on_connect({shared_from_this()});
 
@@ -460,16 +453,45 @@
     conn_->send(string_util::sprintf("USER %s unknown unknown :%s", username_, realname_));
 }
 
+void server::wait()
+{
+    assert(state_ == state_t::waiting);
+
+    timer_.expires_from_now(boost::posix_time::seconds(recodelay_));
+    timer_.async_wait([this] (auto) {
+        recocur_ ++;
+        connect();
+    });
+}
+
 void server::handle_connect(boost::system::error_code code)
 {
     if (code) {
-        // TODO: reconnect happens HERE.
-        state_ = state_t::disconnected;
         conn_ = nullptr;
         log::warning(string_util::sprintf("server %s: error while connecting", name_));
         log::warning(string_util::sprintf("server %s: %s", name_, code.message()));
+
+        // Wait before reconnecting.
+        if (recotries_ != 0) {
+            if (recotries_ > 0 && recocur_ >= recotries_) {
+                log::warning() << "server " << name_ << ": giving up" << std::endl;
+
+                state_ = state_t::disconnected;
+                on_die();
+            } else {
+                log::warning() << "server " << name_ << ": retrying in " <<
+                    recodelay_ << " seconds" << std::endl;
+
+                state_ = state_t::waiting;
+                wait();
+            }
+        } else
+            state_ = state_t::disconnected;
     } else {
         state_ = state_t::identifying;
+        recocur_ = 0U;
+        jchannels_.clear();
+
         identify();
         recv();
     }
@@ -495,7 +517,7 @@
 
 void server::connect() noexcept
 {
-    assert(state_ == state_t::disconnected);
+    assert(state_ == state_t::disconnected || state_ == state_t::waiting);
     /*
      * This is needed if irccd is started before DHCP or if DNS cache is
      * outdated.
--- a/libirccd/irccd/server.hpp	Tue Dec 05 14:54:45 2017 +0100
+++ b/libirccd/irccd/server.hpp	Tue Dec 05 15:31:57 2017 +0100
@@ -420,6 +420,7 @@
 
     // Misc.
     boost::asio::io_service& service_;
+    boost::asio::deadline_timer timer_;
     std::unique_ptr<irc::connection> conn_;
     std::int8_t recocur_{0};
     std::map<std::string, std::set<std::string>> names_map_;
@@ -450,6 +451,7 @@
     void handle_connect(boost::system::error_code);
     void recv();
     void identify();
+    void wait();
 
 public:
     /**