Use a timer to try reconnecting to the XMPP server only each 2 seconds
When the connection is lost, immediately try to reconnect, then try to reconnect every 2 seconds. This is much better than the previous “Try to re-connect as fast as possible”.
This commit is contained in:
+21
-2
@@ -108,6 +108,8 @@ int main(int ac, char** av)
|
||||
exiting = true;
|
||||
stop.store(false);
|
||||
xmpp_component->shutdown();
|
||||
// Cancel the timer for an potential reconnection
|
||||
TimedEventsManager::instance().cancel("XMPP reconnection");
|
||||
}
|
||||
if (reload)
|
||||
{
|
||||
@@ -127,17 +129,34 @@ int main(int ac, char** av)
|
||||
if (!exiting && xmpp_component->ever_auth &&
|
||||
!xmpp_component->is_connected() &&
|
||||
!xmpp_component->is_connecting())
|
||||
{
|
||||
{
|
||||
if (xmpp_component->first_connection_try == true)
|
||||
{ // immediately re-try to connect
|
||||
xmpp_component->reset();
|
||||
xmpp_component->start();
|
||||
}
|
||||
else
|
||||
{ // Re-connecting failed, we now try only each few seconds
|
||||
auto reconnect_later = [xmpp_component]()
|
||||
{
|
||||
xmpp_component->reset();
|
||||
xmpp_component->start();
|
||||
};
|
||||
TimedEvent event(std::chrono::steady_clock::now() + 2s,
|
||||
reconnect_later, "XMPP reconnection");
|
||||
TimedEventsManager::instance().add_event(std::move(event));
|
||||
}
|
||||
}
|
||||
// If the only existing connection is the one to the XMPP component:
|
||||
// close the XMPP stream.
|
||||
if (exiting && xmpp_component->is_connecting())
|
||||
xmpp_component->close();
|
||||
if (exiting && p->size() == 1 && xmpp_component->is_document_open())
|
||||
xmpp_component->close_document();
|
||||
timeout = TimedEventsManager::instance().get_timeout();
|
||||
if (exiting) // If we are exiting, do not wait for any timed event
|
||||
timeout = utils::no_timeout;
|
||||
else
|
||||
timeout = TimedEventsManager::instance().get_timeout();
|
||||
}
|
||||
log_info("All connections cleanly closed, have a nice day.");
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <network/poller.hpp>
|
||||
#include <logger/logger.hpp>
|
||||
#include <utils/timed_events.hpp>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
@@ -133,7 +134,7 @@ void Poller::stop_watching_send_events(SocketHandler* socket_handler)
|
||||
|
||||
int Poller::poll(const std::chrono::milliseconds& timeout)
|
||||
{
|
||||
if (this->socket_handlers.empty())
|
||||
if (this->socket_handlers.empty() && timeout == utils::no_timeout)
|
||||
return -1;
|
||||
#if POLLER == POLL
|
||||
int nb_events = ::poll(this->fds, this->nfds, timeout.count());
|
||||
|
||||
@@ -213,8 +213,11 @@ ssize_t TCPSocketHandler::do_recv(void* recv_buf, const size_t buf_size)
|
||||
else if (-1 == size)
|
||||
{
|
||||
log_warning("Error while reading from socket: " << strerror(errno));
|
||||
// Remember if we were connecting, or already connected when this
|
||||
// happened, because close() sets this->connecting to false
|
||||
const auto were_connecting = this->connecting;
|
||||
this->close();
|
||||
if (this->connecting)
|
||||
if (were_connecting)
|
||||
this->on_connection_failed(strerror(errno));
|
||||
else
|
||||
this->on_connection_close(strerror(errno));
|
||||
|
||||
@@ -39,6 +39,7 @@ static std::set<std::string> kickable_errors{
|
||||
XmppComponent::XmppComponent(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& secret):
|
||||
TCPSocketHandler(poller),
|
||||
ever_auth(false),
|
||||
first_connection_try(true),
|
||||
served_hostname(hostname),
|
||||
secret(secret),
|
||||
authenticated(false),
|
||||
@@ -86,6 +87,7 @@ void XmppComponent::send_stanza(const Stanza& stanza)
|
||||
|
||||
void XmppComponent::on_connection_failed(const std::string& reason)
|
||||
{
|
||||
this->first_connection_try = false;
|
||||
log_error("Failed to connect to the XMPP server: " << reason);
|
||||
#ifdef SYSTEMDDAEMON_FOUND
|
||||
sd_notifyf(0, "STATUS=Failed to connect to the XMPP server: %s", reason.data());
|
||||
@@ -95,6 +97,7 @@ void XmppComponent::on_connection_failed(const std::string& reason)
|
||||
void XmppComponent::on_connected()
|
||||
{
|
||||
log_info("connected to XMPP server");
|
||||
this->first_connection_try = true;
|
||||
XmlNode node("", nullptr);
|
||||
node.set_name("stream:stream");
|
||||
node["xmlns"] = COMPONENT_NS;
|
||||
|
||||
@@ -241,6 +241,12 @@ public:
|
||||
* Whether or not we ever succeeded our authentication to the XMPP server
|
||||
*/
|
||||
bool ever_auth;
|
||||
/**
|
||||
* Whether or not this is the first consecutive try on connecting to the
|
||||
* XMPP server. We use this to delay the connection attempt for a few
|
||||
* seconds, if it is not the first try.
|
||||
*/
|
||||
bool first_connection_try;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user