Changeset - 090a7e5e230b
[Not reviewed]
0 4 0
Jan Kaluza - 14 years ago 2011-07-20 08:17:55
hanzz.k@gmail.com
Fixed crazy backends spawning when one backend stopped sending PONGs
4 files changed with 19 insertions and 24 deletions:
0 comments (0 inline, 0 general)
include/transport/networkpluginserver.h
Show inline comments
 
@@ -40,13 +40,13 @@ class NetworkConversation;
 
class VCardResponder;
 
class RosterResponder;
 

	
 
class NetworkPluginServer {
 
	public:
 
		struct Backend {
 
			bool pongReceived;
 
			int pongReceived;
 
			std::list<User *> users;
 
			Swift::SafeByteArray data;
 
			boost::shared_ptr<Swift::Connection> connection;
 
			unsigned long res;
 
			unsigned long init_res;
 
			unsigned long shared;
include/transport/usermanager.h
Show inline comments
 
@@ -86,13 +86,13 @@ class UserManager {
 
	private:
 
		void handlePresence(Swift::Presence::ref presence);
 
		void handleMessageReceived(Swift::Message::ref message);
 
		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<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
 
		void addUser(User *user);
 

	
 
		long m_onlineBuddies;
 
		User *m_cachedUser;
 
		std::map<std::string, User *> m_users;
src/networkpluginserver.cpp
Show inline comments
 
@@ -137,13 +137,13 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
 
	m_config = config;
 
	m_component = component;
 
	m_component->m_factory = new NetworkFactory(this);
 
	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();
 

	
 
	m_vcardResponder = new VCardResponder(component->getIQRouter(), userManager);
 
	m_vcardResponder->onVCardRequired.connect(boost::bind(&NetworkPluginServer::handleVCardRequired, this, _1, _2, _3));
 
	m_vcardResponder->onVCardUpdated.connect(boost::bind(&NetworkPluginServer::handleVCardUpdated, this, _1, _2));
 
@@ -174,13 +174,13 @@ NetworkPluginServer::~NetworkPluginServer() {
 
	delete m_vcardResponder;
 
	delete m_rosterResponder;
 
}
 

	
 
void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Connection> c) {
 
	Backend *client = new Backend;
 
	client->pongReceived = true;
 
	client->pongReceived = -1;
 
	client->connection = c;
 
	client->res = 0;
 
	client->init_res = 0;
 
	client->shared = 0;
 

	
 
	LOG4CXX_INFO(logger, "New backend " << client << " connected. Current backend count=" << (m_clients.size() + 1));
 
@@ -192,12 +192,13 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Con
 

	
 
	m_clients.push_back(client);
 

	
 
	c->onDisconnected.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()) {
 
		// 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)
 
@@ -559,18 +560,21 @@ void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const st
 
	c->write(Swift::createSafeByteArray(std::string(header, 4) + data));
 
}
 

	
 
void NetworkPluginServer::pingTimeout() {
 
	// check ping responses
 
	for (std::list<Backend *>::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();
 
}
 

	
 
void NetworkPluginServer::handleUserCreated(User *user) {
 
	Backend *c = getFreeClient();
 
@@ -901,30 +905,18 @@ void NetworkPluginServer::sendPing(Backend *c) {
 
NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient() {
 
	NetworkPluginServer::Backend *c = NULL;
 
	bool spawnNew = false;
 
	for (std::list<Backend *>::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());
 
	}
 

	
 
	return c;
 
}
 

	
src/usermanager.cpp
Show inline comments
 
@@ -185,25 +185,28 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 

	
 
	if (presence->getType() == Swift::Presence::Unavailable) {
 
		if (user) {
 
			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();
 
			}
 
		}
 
		// TODO: HANDLE MUC SOMEHOW
 
// 		else if (user && Transport::instance()->protocol()->tempAccountsAllowed() && !((User *) user)->hasOpenedMUC()) {
 
// 			Transport::instance()->userManager()->removeUser(user);
 
// 		}
 
	}
 
}
 

	
 
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) {
 
	User *user = getUser(message->getFrom().toBare().toString());
 
	if (!user ){
 
		return;
0 comments (0 inline, 0 general)