diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index ec9c39bc..7428eb6f 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -43,7 +43,7 @@ class RosterResponder; class NetworkPluginServer { public: struct Backend { - bool pongReceived; + int pongReceived; std::list users; Swift::SafeByteArray data; boost::shared_ptr connection; diff --git a/include/transport/usermanager.h b/include/transport/usermanager.h index 507af267..076cb85b 100644 --- a/include/transport/usermanager.h +++ b/include/transport/usermanager.h @@ -89,7 +89,7 @@ class UserManager { void handleGeneralPresenceReceived(Swift::Presence::ref presence); void handleProbePresence(Swift::Presence::ref presence); void handleSubscription(Swift::Presence::ref presence); - void handleRemoveTimeout(User *user); + void handleRemoveTimeout(const std::string jid); // void handleDiscoInfoResponse(boost::shared_ptr info, Swift::ErrorPayload::ref error, const Swift::JID& jid); void addUser(User *user); diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 39db7ec0..302f642d 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -140,7 +140,7 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1)); m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1)); - m_pingTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(10000); + m_pingTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(20000); m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this)); m_pingTimer->start(); @@ -177,7 +177,7 @@ NetworkPluginServer::~NetworkPluginServer() { void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr c) { Backend *client = new Backend; - client->pongReceived = true; + client->pongReceived = -1; client->connection = c; client->res = 0; client->init_res = 0; @@ -195,6 +195,7 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptronDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, client)); c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, client, _1)); sendPing(client); + client->pongReceived = -1; // some users are in queue waiting for this backend while(!m_waitingUsers.empty()) { @@ -562,12 +563,15 @@ void NetworkPluginServer::send(boost::shared_ptr &c, const st void NetworkPluginServer::pingTimeout() { // check ping responses for (std::list::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { - if ((*it)->pongReceived) { + if ((*it)->pongReceived || (*it)->pongReceived == -1) { sendPing((*it)); } else { - exec_(CONFIG_STRING(m_config, "service.backend").c_str(), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str()); + LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". PING response not received."); + (*it)->connection->disconnect(); + (*it)->connection.reset(); } + } m_pingTimer->start(); } @@ -904,24 +908,12 @@ NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient() { for (std::list::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { // This backend is free. if ((*it)->users.size() < CONFIG_INT(m_config, "service.users_per_backend")) { - // After this user, this backend could be full, so we have to spawn new one... - if ((*it)->users.size() + 1 >= CONFIG_INT(m_config, "service.users_per_backend")) { - spawnNew = true; - } - - if (c == NULL) { - c = *it; - } - else { - if ((*it)->users.size() + 1 != CONFIG_INT(m_config, "service.users_per_backend")) { - spawnNew = false; - break; - } - } + c = *it; + break; } } - if (spawnNew || c == NULL) { + if (c == NULL) { exec_(CONFIG_STRING(m_config, "service.backend").c_str(), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str()); } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 345e32e4..528f3739 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -188,7 +188,7 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(presence->getFrom().toBare()); // There's no presence for this user, so disconnect if (!highest || (highest && highest->getType() == Swift::Presence::Unavailable)) { - m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user)); + m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user->getJID().toBare().toString())); m_removeTimer->start(); } } @@ -199,8 +199,11 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { } } -void UserManager::handleRemoveTimeout(User *user) { - removeUser(user); +void UserManager::handleRemoveTimeout(const std::string jid) { + User *user = getUser(jid); + if (user) { + removeUser(user); + } } void UserManager::handleMessageReceived(Swift::Message::ref message) {