From 2ae5cba932b17fbc7400eb9d9be9b7593dc4effa Mon Sep 17 00:00:00 2001 From: HanzZ Date: Thu, 27 Dec 2012 15:02:21 +0100 Subject: [PATCH] service.login_delay --- include/transport/networkpluginserver.h | 6 ++- src/config.cpp | 1 + src/networkpluginserver.cpp | 67 +++++++++++++++++-------- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 563d7080..738a0cc8 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -141,7 +141,9 @@ class NetworkPluginServer { void pingTimeout(); void sendPing(Backend *c); - Backend *getFreeClient(bool acceptUsers = true, bool longRun = false); + Backend *getFreeClient(bool acceptUsers = true, bool longRun = false, bool check = false); + void connectWaitingUsers(); + void loginDelayFinished(); UserManager *m_userManager; VCardResponder *m_vcardResponder; @@ -152,6 +154,7 @@ class NetworkPluginServer { std::list m_clients; Swift::Timer::ref m_pingTimer; Swift::Timer::ref m_collectTimer; + Swift::Timer::ref m_loginTimer; Component *m_component; std::list m_waitingUsers; bool m_isNextLongRun; @@ -161,6 +164,7 @@ class NetworkPluginServer { AdminInterface *m_adminInterface; bool m_startingBackend; DiscoItemsResponder *m_discoItemsResponder; + time_t m_lastLogin; }; } diff --git a/src/config.cpp b/src/config.cpp index 73b14d09..8873c862 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -98,6 +98,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description ("service.enable_privacy_lists", value()->default_value(true), "") ("service.enable_xhtml", value()->default_value(true), "") ("service.max_room_list_size", value()->default_value(100), "") + ("service.login_delay", value()->default_value(0), "") ("service.jid_escaping", value()->default_value(true), "") ("service.vip_only", value()->default_value(false), "") ("service.vip_message", value()->default_value(""), "") diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 55f3b335..a012ee87 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -258,6 +258,7 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U m_isNextLongRun = false; m_adminInterface = NULL; m_startingBackend = false; + m_lastLogin = 0; m_discoItemsResponder = discoItemsResponder; m_component->m_factory = new NetworkFactory(this); m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1)); @@ -267,6 +268,10 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this)); m_pingTimer->start(); + m_loginTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(config, "service.login_delay") * 1000); + m_loginTimer->onTick.connect(boost::bind(&NetworkPluginServer::loginDelayFinished, this)); + m_loginTimer->start(); + if (CONFIG_INT(m_config, "service.memory_collector_time") != 0) { m_collectTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(m_config, "service.memory_collector_time")); m_collectTimer->onTick.connect(boost::bind(&NetworkPluginServer::collectBackend, this)); @@ -355,6 +360,11 @@ void NetworkPluginServer::start() { } } +void NetworkPluginServer::loginDelayFinished() { + m_loginTimer->stop(); + connectWaitingUsers(); +} + void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr c) { // Create new Backend instance Backend *client = new Backend; @@ -857,6 +867,29 @@ void NetworkPluginServer::handleFTDataNeeded(Backend *b, unsigned long ftid) { send(b->connection, message); } +void NetworkPluginServer::connectWaitingUsers() { + // some users are in queue waiting for this backend + while(!m_waitingUsers.empty()) { + // There's no new backend, so stop associating users and wait for new backend, + // which has been already spawned in getFreeClient() call. + if (getFreeClient(true, false, true) == NULL) + break; + + User *u = m_waitingUsers.front(); + m_waitingUsers.pop_front(); + + LOG4CXX_INFO(logger, "Associating " << u->getJID().toString() << " with this backend"); + + // associate backend with user + handleUserCreated(u); + + // connect user if it's ready + if (u->isReadyToConnect()) { + handleUserReadyToConnect(u); + } + } +} + void NetworkPluginServer::handlePongReceived(Backend *c) { // This could be first PONG from the backend if (c->pongReceived == -1) { @@ -868,26 +901,7 @@ void NetworkPluginServer::handlePongReceived(Backend *c) { m_component->start(); } - // some users are in queue waiting for this backend - while(!m_waitingUsers.empty()) { - // There's no new backend, so stop associating users and wait for new backend, - // which has been already spawned in getFreeClient() call. - if (getFreeClient() == NULL) - break; - - User *u = m_waitingUsers.front(); - m_waitingUsers.pop_front(); - - LOG4CXX_INFO(logger, "Associating " << u->getJID().toString() << " with this backend"); - - // associate backend with user - handleUserCreated(u); - - // connect user if it's ready - if (u->isReadyToConnect()) { - handleUserReadyToConnect(u); - } - } + connectWaitingUsers(); } c->pongReceived = true; @@ -1642,9 +1656,20 @@ void NetworkPluginServer::sendPing(Backend *c) { // LOG4CXX_INFO(logger, "PING to " << c); } -NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient(bool acceptUsers, bool longRun) { +NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient(bool acceptUsers, bool longRun, bool check) { NetworkPluginServer::Backend *c = NULL; + unsigned long diff = CONFIG_INT(m_config, "service.login_delay"); + time_t now = time(NULL); + if (diff && (now - m_lastLogin < diff)) { + m_loginTimer->start(); + return NULL; + } + + if (!check) { + m_lastLogin = time(NULL); + } + // Check all backends and find free one for (std::list::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { if ((*it)->willDie == false && (*it)->acceptUsers == acceptUsers && (*it)->users.size() < CONFIG_INT(m_config, "service.users_per_backend") && (*it)->connection && (*it)->longRun == longRun) {