Added TaskManager app

This commit is contained in:
Anonymous
2014-01-16 20:06:39 -07:00
parent 39e541c767
commit 2bcd8a262c
46 changed files with 4822 additions and 0 deletions
@@ -0,0 +1,115 @@
// CentralConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "CentralConnection.h"
#include "TaskConnection.h"
#include "TaskManager.h"
#include "serverNetworkMessages/PreloadFinishedMessage.h"
#include "serverNetworkMessages/TaskSpawnProcess.h"
#include "sharedNetworkMessages/ConsoleChannelMessages.h"
#include "sharedFoundation/Clock.h"
#include "sharedMessageDispatch/Transceiver.h"
//-----------------------------------------------------------------------
CentralConnection::CentralConnection(TaskConnection * c, const std::string & n) :
TaskHandler(),
callback(),
commandLine(n),
connected(true),
connection(c),
lastSpawnTime(Clock::timeMs())
{
callback.connect(c->getTransceiverClosed(), *this, &CentralConnection::closed); //lint !e1025 !e1703 !e1514 !e64
callback.connect(*this, &CentralConnection::onProcessKilled); //lint !e1025 !e1703 !e1514 !e64 !e1058 !e118
// TaskManager::startServer("ConnectionServer", "");
// TaskManager::startServer("SwgDatabaseServer", "");
}
//-----------------------------------------------------------------------
CentralConnection::~CentralConnection()
{
connection = 0;
}
//-----------------------------------------------------------------------
void CentralConnection::closed(const Closed &)
{
if(connected)
{
ProcessAborted a;
a.commandLine = commandLine;
a.hostName = NetworkHandler::getHostName();
MessageDispatch::Transceiver<const ProcessAborted &> b;
b.emitMessage(a);
unsigned long t = Clock::timeMs();
if(t - lastSpawnTime > 5000) // stop spawning if it bombs immediately
{
lastSpawnTime = t;
// need to restart it!
//IGNORE_RETURN(TaskManager::startServer(commandLine));
}
else
{
// emit the killed message
ProcessKilled k;
k.commandLine = a.commandLine;
k.hostName = a.hostName;
MessageDispatch::Transceiver<const ProcessKilled &> pk;
pk.emitMessage(k);
}
connected = false;
TaskManager::setCentralConnection(0);
}
}
//-----------------------------------------------------------------------
void CentralConnection::onProcessKilled(const ProcessKilled & k)
{
if(k.commandLine == commandLine)
lastSpawnTime = Clock::timeMs(); // force it to stay dead
}
//-----------------------------------------------------------------------
void CentralConnection::receive(const Archive::ByteStream & message)
{
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
r = message.begin();
if(m.isType("TaskSpawnProcess"))
{
TaskSpawnProcess s(r);
IGNORE_RETURN(TaskManager::startServer(s.getProcessName(), s.getOptions(), s.getTargetHostAddress(), s.getSpawnDelay()));
}
else if(m.isType("PreloadFinishedMessage"))
{
PreloadFinishedMessage m(r);
if (m.getFinished())
TaskManager::onPreloadFinished();
}
else if(m.isType("ConGenericMessage"))
{
ConGenericMessage taskConsoleCommand(r);
static std::string command = taskConsoleCommand.getMsg();
while(command.rfind(' ') != command.npos || command.rfind('\n') != command.npos || command.rfind('\r') != command.npos)
{
command = command.substr(0, command.length() - 1);
}
TaskManager::executeCommand(command);
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,42 @@
// CentralConnection.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_CentralConnection_H
#define _INCLUDED_CentralConnection_H
//-----------------------------------------------------------------------
#include "sharedMessageDispatch/Transceiver.h"
#include "TaskHandler.h"
class TaskConnection;
struct Closed;
//-----------------------------------------------------------------------
class CentralConnection : public TaskHandler
{
public:
CentralConnection(TaskConnection * newConnection, const std::string & commandLine);
~CentralConnection();
void closed(const Closed &);
void receive(const Archive::ByteStream & message);
private:
CentralConnection & operator = (const CentralConnection & rhs);
CentralConnection(const CentralConnection & source);
void onProcessKilled(const struct ProcessKilled &);
private:
MessageDispatch::Callback callback;
std::string commandLine;
bool connected;
TaskConnection * connection;
unsigned long lastSpawnTime;
}; //lint !e1712 default constructor not defined for class 'CentralConnection'
//-----------------------------------------------------------------------
#endif // _INCLUDED_CentralConnection_H
@@ -0,0 +1,108 @@
// ConfigTaskManager.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedNetwork/SetupSharedNetwork.h"
#include "ConfigTaskManager.h"
#include <vector>
//-----------------------------------------------------------------------
ConfigTaskManager::Data * ConfigTaskManager::data = 0;
#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("TaskManager", #a, b))
#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("TaskManager", #a, b))
#define KEY_FLOAT(a,b) (data->a = ConfigFile::getKeyFloat("TaskManager", #a, b))
#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("TaskManager", #a, b))
//-----------------------------------------------------------------------
namespace ConfigTaskManagerNamespace
{
typedef std::vector<char const *> StringPtrArray;
StringPtrArray ms_environmentVariable; // ConfigFile owns the pointer
}
using namespace ConfigTaskManagerNamespace;
// ======================================================================
int ConfigTaskManager::getNumberOfEnvironmentVariables()
{
return static_cast<int>(ms_environmentVariable.size());
}
// ----------------------------------------------------------------------
char const * ConfigTaskManager::getEnvironmentVariable(int index)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfEnvironmentVariables());
return ms_environmentVariable[static_cast<size_t>(index)];
}
// ----------------------------------------------------------------------
void ConfigTaskManager::install(void)
{
SetupSharedNetwork::SetupData networkSetupData;
SetupSharedNetwork::getDefaultServerSetupData(networkSetupData);
SetupSharedNetwork::install(networkSetupData);
data = new ConfigTaskManager::Data;
KEY_BOOL (autoStart, true);
KEY_STRING (clusterName, "devcluster");
KEY_BOOL (verifyClusterName, false);
KEY_INT (gameServerTimeout, 600);
KEY_STRING (gameServiceBindInterface, "");
KEY_INT (gameServicePort, 60001);
KEY_INT (consoleConnectionPort, 60000);
KEY_STRING (consoleServiceBindInterface, "");
KEY_STRING (loginServerAddress, "swo-dev5.station.sony.com");
KEY_INT (loginServerTaskServicePort, 44459);
KEY_FLOAT (maximumLoad, 3.0f);
KEY_FLOAT (loadConnectionServer, 0.5f);
KEY_FLOAT (loadPlanetServer, 0.128f);
KEY_FLOAT (loadGameServer, 1.0f);
KEY_BOOL (publishMode, false);
KEY_STRING (rcFileName, "taskmanager.rc");
KEY_BOOL (restartCentral, false);
KEY_INT (restartDelayCentralServer, 60); // seconds
KEY_INT (restartDelayLogServer, 30);
KEY_INT (restartDelayMetricsServer, 60);
KEY_INT (restartDelayCommoditiesServer, 60);
KEY_INT (restartDelayTransferServer, 30);
KEY_STRING (taskManagerServiceBindInterface, "");
KEY_INT (taskManagerServicePort, 50001);
KEY_INT (maximumClockDriftToleranceSeconds, 10); // seconds
KEY_INT (systemTimeCheckIntervalSeconds, 60); // seconds
KEY_INT (clockDriftFatalIntervalSeconds, 1*60*60); // seconds
int index = 0;
char const * result = 0;
do
{
result = ConfigFile::getKeyString("TaskManager", "environmentVariable", index++, 0);
if (result != 0)
{
ms_environmentVariable.push_back(result);
}
}
while (result);
}
//-----------------------------------------------------------------------
void ConfigTaskManager::remove(void)
{
delete data;
data = 0;
}
//-----------------------------------------------------------------------
@@ -0,0 +1,273 @@
// ConfigTaskManager.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _ConfigTaskManager_H
#define _ConfigTaskManager_H
//-----------------------------------------------------------------------
class ConfigTaskManager
{
public:
struct Data
{
bool autoStart;
const char * clusterName;
bool verifyClusterName;
int consoleConnectionPort;
const char * consoleServiceBindInterface;
unsigned long gameServerTimeout;
const char * gameServiceBindInterface;
int gameServicePort;
const char * loginServerAddress;
int loginServerTaskServicePort;
float maximumLoad;
float loadConnectionServer;
float loadPlanetServer;
float loadGameServer;
bool publishMode;
const char * rcFileName;
bool restartCentral;
int restartDelayCentralServer;
int restartDelayLogServer;
int restartDelayMetricsServer;
int restartDelayCommoditiesServer;
int restartDelayTransferServer;
int taskManagerServicePort;
const char * taskManagerServiceBindInterface;
int maximumClockDriftToleranceSeconds;
int systemTimeCheckIntervalSeconds;
int clockDriftFatalIntervalSeconds;
};
static const bool getAutoStart ();
static const char * getClusterName ();
static const bool getVerifyClusterName ();
static const uint16 getConsoleConnectionPort ();
static const char * getConsoleServiceBindInterface ();
static const char * getLoginServerAddress ();
static const uint16 getLoginServerTaskServicePort ();
static const bool getPublishMode();
static const char * getRcFileName ();
static bool getRestartCentral();
static unsigned int getRestartDelayCentralServer ();
static unsigned int getRestartDelayLogServer ();
static unsigned int getRestartDelayMetricsServer ();
static unsigned int getRestartDelayCommoditiesServer ();
static unsigned int getRestartDelayTransferServer ();
static unsigned long getGameServerTimeout ();
static const char * getGameServiceBindInterface ();
static uint16 getGameServicePort();
static float getMaximumLoad ();
static float getLoadConnectionServer ();
static float getLoadPlanetServer ();
static float getLoadGameServer ();
static uint16 getTaskManagerServicePort();
static const char * getTaskManagerServiceBindInterface();
static int getMaximumClockDriftToleranceSeconds();
static int getSystemTimeCheckIntervalSeconds();
static int getClockDriftFatalIntervalSeconds();
static void install ();
static void remove ();
static int getNumberOfEnvironmentVariables();
static char const * getEnvironmentVariable(int index);
private:
static Data * data;
};
//-----------------------------------------------------------------------
inline const bool ConfigTaskManager::getAutoStart()
{
return data->autoStart;
}
//-----------------------------------------------------------------------
inline const char * ConfigTaskManager::getClusterName()
{
return data->clusterName;
}
//-----------------------------------------------------------------------
inline const bool ConfigTaskManager::getVerifyClusterName()
{
return data->verifyClusterName;
}
//-----------------------------------------------------------------------
inline const uint16 ConfigTaskManager::getConsoleConnectionPort()
{
return static_cast<uint16>(data->consoleConnectionPort);
}
//-----------------------------------------------------------------------
inline uint16 ConfigTaskManager::getGameServicePort()
{
return static_cast<uint16>(data->gameServicePort);
}
//-----------------------------------------------------------------------
inline uint16 ConfigTaskManager::getTaskManagerServicePort()
{
return static_cast<uint16>(data->taskManagerServicePort);
}
//-----------------------------------------------------------------------
inline const char * ConfigTaskManager::getLoginServerAddress()
{
return data->loginServerAddress;
}
//-----------------------------------------------------------------------
inline const uint16 ConfigTaskManager::getLoginServerTaskServicePort()
{
return static_cast<uint16>(data->loginServerTaskServicePort);
}
//-----------------------------------------------------------------------
inline const char * ConfigTaskManager::getRcFileName()
{
return data->rcFileName;
}
//-----------------------------------------------------------------------
inline const char * ConfigTaskManager::getConsoleServiceBindInterface()
{
return data->consoleServiceBindInterface;
}
//-----------------------------------------------------------------------
inline const char * ConfigTaskManager::getGameServiceBindInterface()
{
return data->gameServiceBindInterface;
}
//-----------------------------------------------------------------------
inline const char * ConfigTaskManager::getTaskManagerServiceBindInterface()
{
return data->taskManagerServiceBindInterface;
}
//-----------------------------------------------------------------------
inline const bool ConfigTaskManager::getPublishMode()
{
return data->publishMode;
}
//-----------------------------------------------------------------------
inline float ConfigTaskManager::getMaximumLoad()
{
return data->maximumLoad;
}
//-----------------------------------------------------------------------
inline float ConfigTaskManager::getLoadConnectionServer()
{
return data->loadConnectionServer;
}
//-----------------------------------------------------------------------
inline float ConfigTaskManager::getLoadPlanetServer()
{
return data->loadPlanetServer;
}
//-----------------------------------------------------------------------
inline float ConfigTaskManager::getLoadGameServer()
{
return data->loadGameServer;
}
// ----------------------------------------------------------------------
inline unsigned long ConfigTaskManager::getGameServerTimeout()
{
return data->gameServerTimeout;
}
// ----------------------------------------------------------------------
inline bool ConfigTaskManager::getRestartCentral()
{
return data->restartCentral;
}
// ----------------------------------------------------------------------
inline unsigned int ConfigTaskManager::getRestartDelayCentralServer()
{
return static_cast<unsigned int>(data->restartDelayCentralServer);
}
// ----------------------------------------------------------------------
inline unsigned int ConfigTaskManager::getRestartDelayLogServer()
{
return static_cast<unsigned int>(data->restartDelayLogServer);
}
// ----------------------------------------------------------------------
inline unsigned int ConfigTaskManager::getRestartDelayMetricsServer()
{
return static_cast<unsigned int>(data->restartDelayMetricsServer);
}
// ----------------------------------------------------------------------
inline unsigned int ConfigTaskManager::getRestartDelayCommoditiesServer()
{
return static_cast<unsigned int>(data->restartDelayCommoditiesServer);
}
// ----------------------------------------------------------------------
inline unsigned int ConfigTaskManager::getRestartDelayTransferServer()
{
return static_cast<unsigned int>(data->restartDelayTransferServer);
}
// ----------------------------------------------------------------------
inline int ConfigTaskManager::getMaximumClockDriftToleranceSeconds()
{
return data->maximumClockDriftToleranceSeconds;
}
// ----------------------------------------------------------------------
inline int ConfigTaskManager::getSystemTimeCheckIntervalSeconds()
{
return data->systemTimeCheckIntervalSeconds;
}
// ----------------------------------------------------------------------
inline int ConfigTaskManager::getClockDriftFatalIntervalSeconds()
{
return data->clockDriftFatalIntervalSeconds;
}
// ----------------------------------------------------------------------
#endif // _ConfigTaskManager_H
@@ -0,0 +1,73 @@
// Console.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "ConfigTaskManager.h"
#include "Console.h"
#include "ConsoleImplementation.h"
#include <cstdio>
//-----------------------------------------------------------------------
Console::Console() :
consoleImplementation(new ConsoleImplementation)
{
}
//-----------------------------------------------------------------------
Console::~Console()
{
delete consoleImplementation;
}
//-----------------------------------------------------------------------
Console & Console::instance()
{
static Console console;
return console;
}
//-----------------------------------------------------------------------
const std::string Console::getNextCommand()
{
return instance().consoleImplementation->popNextCommand();
}
//-----------------------------------------------------------------------
const bool Console::hasPendingCommand()
{
return instance().consoleImplementation->hasPendingCommand();
}
//-----------------------------------------------------------------------
void Console::update()
{
if(ConfigTaskManager::getAutoStart())
return;
static Console & con = instance();
char ch = 0;
while((ch = con.getNextChar()) != 0)
{
if(ch == 10 || ch == 13)
{
con.consoleImplementation->pushCommand(con.currentCommand);
con.currentCommand.clear();
}
else
{
con.currentCommand += ch;
}
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,41 @@
// Console.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_Console_H
#define _INCLUDED_Console_H
//-----------------------------------------------------------------------
#include <string>
//-----------------------------------------------------------------------
class ConsoleImplementation;
//-----------------------------------------------------------------------
class Console
{
public:
~Console();
static const bool hasPendingCommand ();
static const std::string getNextCommand ();
static void update ();
private:
Console();
Console & operator = (const Console & rhs);
Console(const Console & source);
static Console & instance();
const char getNextChar();
private:
ConsoleImplementation * consoleImplementation;
std::string currentCommand;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_Console_H
@@ -0,0 +1,60 @@
// ConsoleConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "Archive/ByteStream.h"
#include "ConsoleConnection.h"
#include "sharedNetworkMessages/ConsoleChannelMessages.h"
#include "TaskManager.h"
//-----------------------------------------------------------------------
ConsoleConnection::ConsoleConnection(UdpConnectionMT * udpConnection, TcpClient * t) :
ServerConnection(udpConnection, t)
{
}
//-----------------------------------------------------------------------
ConsoleConnection::~ConsoleConnection()
{
}
//-----------------------------------------------------------------------
void ConsoleConnection::onReceive(const Archive::ByteStream & message)
{
static Archive::ReadIterator ri;
ri = message.begin();
GameNetworkMessage msg(ri);
if(msg.isType("ConGenericMessage"))
{
ri = message.begin();
ConGenericMessage taskConsoleCommand(ri);
static std::string command;
command = taskConsoleCommand.getMsg();
while(command.rfind(' ') != command.npos || command.rfind('\n') != command.npos || command.rfind('\r') != command.npos)
command = command.substr(0, command.length() - 1);
ConGenericMessage response(TaskManager::executeCommand(command), taskConsoleCommand.getMsgId());
send(response, true);
GameNetworkMessage dis("RequestDisconnect");
send(dis, true);
REPORT_LOG(true, ("Received remote console command from %s : [%s]\n", getRemoteAddress().c_str(), command.c_str()));
}
else
{
// someone is sending the wrong data!
disconnect();
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,30 @@
// ConsoleConnection.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_ConsoleConnection_H
#define _INCLUDED_ConsoleConnection_H
//-----------------------------------------------------------------------
#include "serverUtility/ServerConnection.h"
//-----------------------------------------------------------------------
class ConsoleConnection : public ServerConnection
{
public:
ConsoleConnection(UdpConnectionMT * udpConnection, TcpClient *);
~ConsoleConnection();
virtual void onReceive (const Archive::ByteStream & message);
private:
ConsoleConnection & operator = (const ConsoleConnection & rhs);
ConsoleConnection(const ConsoleConnection & source);
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_ConsoleConnection_H
@@ -0,0 +1,50 @@
// ConsoleImplementation.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "ConsoleImplementation.h"
//-----------------------------------------------------------------------
ConsoleImplementation::ConsoleImplementation()
{
}
//-----------------------------------------------------------------------
ConsoleImplementation::~ConsoleImplementation()
{
}
//-----------------------------------------------------------------------
const bool ConsoleImplementation::hasPendingCommand() const
{
return (!m_pendingCommands.empty());
}
//-----------------------------------------------------------------------
const std::string ConsoleImplementation::popNextCommand()
{
std::string result;
if(hasPendingCommand())
{
result = m_pendingCommands.front();
m_pendingCommands.pop_front();
}
return result;
}
//-----------------------------------------------------------------------
void ConsoleImplementation::pushCommand(const std::string & newCommand)
{
m_pendingCommands.push_back(newCommand);
}
//-----------------------------------------------------------------------
@@ -0,0 +1,34 @@
// ConsoleImplementation.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_ConsoleImplementation_H
#define _INCLUDED_ConsoleImplementation_H
//-----------------------------------------------------------------------
#include <list>
#include <string>
//-----------------------------------------------------------------------
class ConsoleImplementation
{
public:
ConsoleImplementation();
~ConsoleImplementation();
const bool hasPendingCommand () const;
const std::string popNextCommand ();
void pushCommand (const std::string & newCommand);
private:
ConsoleImplementation & operator = (const ConsoleImplementation & rhs);
ConsoleImplementation(const ConsoleImplementation & source);
private:
std::list<std::string> m_pendingCommands;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_ConsoleImplementation_H
@@ -0,0 +1,60 @@
// DatabaseConnection.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "DatabaseConnection.h"
#include "TaskManager.h"
#include "serverNetworkMessages/GameTaskManagerMessages.h"
#include "serverNetworkMessages/TaskSpawnProcess.h"
//-----------------------------------------------------------------------
DatabaseConnection::DatabaseConnection() :
TaskHandler()
{
// TaskManager::startServer("PlanetServer", "");
// TaskManager::startServer("SwgGameServer", "");
}
//-----------------------------------------------------------------------
DatabaseConnection::~DatabaseConnection()
{
}
//-----------------------------------------------------------------------
DatabaseConnection & DatabaseConnection::operator = (const DatabaseConnection & rhs)
{
if(this != &rhs)
{
// make assignments if right hand side is not this instance
}
return *this;
}
//-----------------------------------------------------------------------
void DatabaseConnection::receive(const Archive::ByteStream & message)
{
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
r = message.begin();
if(m.isType("TaskSpawnProcess"))
{
TaskSpawnProcess s(r);
IGNORE_RETURN(TaskManager::startServer(s.getProcessName(), s.getOptions(), s.getTargetHostAddress(), s.getSpawnDelay()));
}
else if(m.isType("ServerIdleMessage"))
{
ServerIdleMessage msg(r);
TaskManager::onDatabaseIdle(msg.getIsIdle());
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,28 @@
// DatabaseConnection.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_DatabaseConnection_H
#define _INCLUDED_DatabaseConnection_H
//-----------------------------------------------------------------------
#include "TaskHandler.h"
//-----------------------------------------------------------------------
class DatabaseConnection : public TaskHandler
{
public:
DatabaseConnection();
~DatabaseConnection();
void receive(const Archive::ByteStream & message);
private:
DatabaseConnection & operator = (const DatabaseConnection & rhs);
DatabaseConnection(const DatabaseConnection & source);
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_DatabaseConnection_H
@@ -0,0 +1,10 @@
namespace EnvironmentVariable
{
//This function takes a string in the form key=value. It will add
//value to the environment variable key if key exists. Otherwise it
//will create a new env called key and set it to value.
bool addToEnvironmentVariable(const char* key, const char* value);
bool setEnvironmentVariable(const char* key, const char* value);
};
@@ -0,0 +1,12 @@
// FirstTaskManager.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
void FirstTaskManagerFoo(){} //lint !e714 // enable #pragma warning disable
//-----------------------------------------------------------------------
@@ -0,0 +1,18 @@
// FirstTaskManager.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_FirstTaskManager_H
#define _INCLUDED_FirstTaskManager_H
//-----------------------------------------------------------------------
#pragma warning ( disable : 4786 )
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundationTypes/FoundationTypes.h"
#include <string>
#include <map>
//-----------------------------------------------------------------------
#endif // _INCLUDED_FirstTaskManager_H
@@ -0,0 +1,175 @@
// GameConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "GameConnection.h"
#include "ConfigTaskManager.h"
#include "Archive/Archive.h"
#include "TaskManager.h"
#include "sharedFoundation/Clock.h"
#include "sharedLog/Log.h"
#include "sharedNetwork/NetworkHandler.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "ProcessSpawner.h"
//-----------------------------------------------------------------------
namespace GameConnectionNamespace
{
std::vector<GameConnection *> s_gameConnections;
}
using namespace GameConnectionNamespace;
//-----------------------------------------------------------------------
GameConnection::GameConnection(TaskConnection * c) :
TaskHandler(),
connection(c),
m_lastKeepalive(0),
m_pid(0),
m_commandLine(),
m_timeLastKilled(0),
m_loggedKill(false),
m_loggedKillForceCore(false)
{
TaskManager::addToGameConnections(1);
s_gameConnections.push_back(this);
}
//-----------------------------------------------------------------------
GameConnection::~GameConnection()
{
std::vector<GameConnection *>::iterator f = std::find(s_gameConnections.begin(), s_gameConnections.end(), this);
if(f != s_gameConnections.end())
s_gameConnections.erase(f);
connection = 0;
TaskManager::addToGameConnections(-1);
}
//-----------------------------------------------------------------------
void GameConnection::install()
{
}
//-----------------------------------------------------------------------
void GameConnection::remove()
{
s_gameConnections.clear();
}
//-----------------------------------------------------------------------
void GameConnection::receive(const Archive::ByteStream & message)
{
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
r = message.begin();
if(m.isType("GameServerTaskManagerKeepAlive"))
{
if(! m_pid)
{
GenericValueTypeMessage<unsigned long> msg(r);
m_pid = msg.getValue();
#ifndef _WIN32
// get the command line
if (m_pid && m_commandLine.empty())
{
char filename[30];
snprintf(filename, sizeof(filename)-1, "/proc/%lu/cmdline", m_pid);
// format of the cmdline file is a NULL separates every
// parameter, so we'll have to replace the NULLs with spaces
FILE *inFile = fopen(filename,"rb");
if (inFile)
{
char buffer[512];
int bytesRead = fread(buffer, 1, sizeof(buffer)-1, inFile);
if ((bytesRead > 0) && (bytesRead < static_cast<int>(sizeof(buffer))))
{
buffer[bytesRead] = '\0';
for (int i = 0; i < bytesRead; ++i)
{
if (buffer[i] == '\0')
{
buffer[i] = ' ';
}
}
m_commandLine = buffer;
}
fclose(inFile);
}
}
#endif
}
m_lastKeepalive = Clock::timeSeconds();
}
}
//-----------------------------------------------------------------------
void GameConnection::update()
{
std::vector<GameConnection *>::iterator i;
std::vector<GameConnection *> v = s_gameConnections;
const unsigned long currentTime = Clock::timeSeconds();
const unsigned long gameServerTimeout = ConfigTaskManager::getGameServerTimeout();
if (gameServerTimeout > 0)
{
for (i = v.begin(); i != v.end(); ++i)
{
GameConnection * g = (*i);
if (g->m_lastKeepalive && g->m_pid && ((g->m_lastKeepalive + gameServerTimeout) < currentTime))
{
// attempt ProcessSpawner::forceCore() once per minute and if that doesn't
// work after a period of gameServerTimeout, then do a ProcessSpawner::kill()
if ((currentTime - g->m_lastKeepalive) > (2 * gameServerTimeout))
{
g->m_timeLastKilled = currentTime;
LOG("ServerHang", ("killing (kill) GameServer %s,%d (%s) because it has not provided a keepalive message in %d seconds", NetworkHandler::getHumanReadableHostName().c_str(), g->m_pid, g->m_commandLine.c_str(), currentTime - g->m_lastKeepalive));
WARNING(true, ("killing (kill) GameServer %s,%d (%s) because it has not provided a keepalive message in %d seconds", NetworkHandler::getHumanReadableHostName().c_str(), g->m_pid, g->m_commandLine.c_str(), currentTime - g->m_lastKeepalive));
// one time logging to customer service channel
if (!g->m_loggedKill)
{
g->m_loggedKill = true;
LOG("TaskManager", ("ServerHang: killing (kill) GameServer %s,%d (%s) because it has not provided a keepalive message in %d seconds", NetworkHandler::getHumanReadableHostName().c_str(), g->m_pid, g->m_commandLine.c_str(), currentTime - g->m_lastKeepalive));
}
ProcessSpawner::kill(g->m_pid);
}
else if ((g->m_timeLastKilled == 0) || ((currentTime - g->m_timeLastKilled) >= 60))
{
g->m_timeLastKilled = currentTime;
LOG("ServerHang", ("killing (forceCore) GameServer %s,%d (%s) because it has not provided a keepalive message in %d seconds", NetworkHandler::getHumanReadableHostName().c_str(), g->m_pid, g->m_commandLine.c_str(), currentTime - g->m_lastKeepalive));
WARNING(true, ("killing (forceCore) GameServer %s,%d (%s) because it has not provided a keepalive message in %d seconds", NetworkHandler::getHumanReadableHostName().c_str(), g->m_pid, g->m_commandLine.c_str(), currentTime - g->m_lastKeepalive));
// one time logging to customer service channel
if (!g->m_loggedKillForceCore)
{
g->m_loggedKillForceCore = true;
LOG("TaskManager", ("ServerHang: killing (forceCore) GameServer %s,%d (%s) because it has not provided a keepalive message in %d seconds", NetworkHandler::getHumanReadableHostName().c_str(), g->m_pid, g->m_commandLine.c_str(), currentTime - g->m_lastKeepalive));
}
ProcessSpawner::forceCore(g->m_pid);
}
}
}
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,43 @@
// GameConnection.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_GameConnection_H
#define _INCLUDED_GameConnection_H
//-----------------------------------------------------------------------
#include "TaskHandler.h"
#include <string>
class TaskConnection;
//-----------------------------------------------------------------------
class GameConnection : public TaskHandler
{
public:
explicit GameConnection(TaskConnection * connection);
~GameConnection();
static void install();
void receive(const Archive::ByteStream & message);
static void remove();
static void update();
private:
GameConnection & operator = (const GameConnection & rhs);
GameConnection(const GameConnection & source);
TaskConnection * connection;
unsigned long m_lastKeepalive;
unsigned long m_pid;
std::string m_commandLine;
unsigned long m_timeLastKilled;
bool m_loggedKill;
bool m_loggedKillForceCore;
}; //lint !e1712
//-----------------------------------------------------------------------
#endif // _INCLUDED_GameConnection_H
@@ -0,0 +1,445 @@
// ======================================================================
//
// Locator.cpp
//
// Copyright 2000-04 Sony Online Entertainment
//
// ======================================================================
#include "FirstTaskManager.h"
#include "Locator.h"
#include "ConfigTaskManager.h"
#include "ManagerConnection.h"
#include "TaskManager.h"
#include "serverNetworkMessages/TaskUtilization.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedLog/Log.h"
#include <algorithm>
#include <vector>
// ======================================================================
namespace LocatorNamespace
{
float getConfigSetting(const char *section, const char *key, const float defaultValue)
{
const ConfigFile::Section * sec = ConfigFile::getSection(section);
if (sec == NULL)
return defaultValue;
const ConfigFile::Key * ky = sec->findKey(key);
if (ky == NULL)
return defaultValue;
return ky->getAsFloat(ky->getCount()-1, defaultValue);
}
struct PreferredNode
{
std::string m_nodeLabel;
std::string m_processName;
std::vector<std::string> m_nodeOptions;
bool match(std::string const &processName, std::string const &options) const
{
if (m_processName != processName)
return false;
for (std::vector<std::string>::const_iterator i = m_nodeOptions.begin(); i != m_nodeOptions.end(); ++i)
if (options.find(*i) == std::string::npos)
return false;
return true;
}
};
struct ServerEntry
{
ServerEntry(ManagerConnection *conn, std::string const &label, float load);
bool operator==(std::string const &label) const
{
return m_label == label;
}
bool operator<(ServerEntry const & rhs) const
{
// don't change this; the code requires that the nodes
// list be ordered by the current load on the node
return m_load < rhs.m_load;
}
bool hasAvailableLoad(float cost) const
{
return ((m_load + cost) < m_maximumLoad);
}
ManagerConnection *m_connection;
std::string m_label;
float m_load;
float m_maximumLoad;
};
ServerEntry::ServerEntry(ManagerConnection *conn, std::string const &label, float load) :
m_connection(conn),
m_label(label),
m_load(load),
m_maximumLoad(0.0f)
{
// see if there is a maximum load specified for this particular node
char key[128];
snprintf(key, sizeof(key)-1, "maximumLoad.%s", m_label.c_str());
key[sizeof(key)-1] = '\0';
m_maximumLoad = getConfigSetting("TaskManager", key, ConfigTaskManager::getMaximumLoad());
}
std::vector<ServerEntry> s_serverList;
const char s_masterNodeLabel[] = "node0";
float s_myLoad;
std::vector<PreferredNode> s_preferredNodes;
std::map<std::string, std::string> s_closedConnections; // to keep track of TaskManager that we have lost connection to which has not yet reconnected
ManagerConnection *getPreferredServer(std::string const &processName, std::string const &options, float cost);
ManagerConnection *getUnpreferredServer(float cost);
void addPreferredNode(std::string const &preferredNodeSpec);
}
using namespace LocatorNamespace;
// ======================================================================
void Locator::install()
{
int index = 0;
char const * result = 0;
do
{
result = ConfigFile::getKeyString("TaskManager", "preferredNode", index++, 0);
if (result)
addPreferredNode(result);
}
while (result);
}
// ----------------------------------------------------------------------
void Locator::closed(std::string const &label, ManagerConnection const *oldConnection)
{
if (oldConnection)
{
std::vector<ServerEntry>::iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if (i != s_serverList.end())
{
DEBUG_REPORT_LOG(true, ("Removing connection %s on %s from locator map\n", label.c_str(), oldConnection->getRemoteAddress().c_str()));
IGNORE_RETURN(s_serverList.erase(i));
s_closedConnections[label] = oldConnection->getRemoteAddress();
}
}
}
// ----------------------------------------------------------------------
ManagerConnection *LocatorNamespace::getPreferredServer(std::string const &processName, std::string const &options, float cost)
{
// Find a node other than the master node that can afford to run the process
// and is a preferred node for the process and option set.
for (std::vector<ServerEntry>::iterator i = s_serverList.begin(); i != s_serverList.end(); ++i)
{
ServerEntry &e = *i;
if ((e.m_label != s_masterNodeLabel) && (e.hasAvailableLoad(cost)))
{
for (std::vector<PreferredNode>::const_iterator j = s_preferredNodes.begin(); j != s_preferredNodes.end(); ++j)
if ((*j).m_nodeLabel == e.m_label && (*j).match(processName, options))
return e.m_connection;
}
}
return 0;
}
// ----------------------------------------------------------------------
ManagerConnection *LocatorNamespace::getUnpreferredServer(float cost)
{
// Find a node other than the master node that can afford to run the process
// and is a not marked as a preferred node for anything; if more than one
// node qualifies, return the node with the lowest load
for (std::vector<ServerEntry>::iterator i = s_serverList.begin(); i != s_serverList.end(); ++i)
{
ServerEntry &e = *i;
if ((e.m_label != s_masterNodeLabel) && (e.hasAvailableLoad(cost)))
{
bool foundPreferred = false;
for (std::vector<PreferredNode>::const_iterator j = s_preferredNodes.begin(); j != s_preferredNodes.end(); ++j)
{
if ((*j).m_nodeLabel == e.m_label)
{
foundPreferred = true;
break;
}
}
// s_serverList is ordered by load, so this will
// return the available node with the lowest load
if (!foundPreferred)
return e.m_connection;
}
}
return 0;
}
// ----------------------------------------------------------------------
ManagerConnection *Locator::getBestServer(std::string const &processName, std::string const &options, float cost)
{
if (s_serverList.empty())
return 0;
// first, look for a preferred node for this process
{
ManagerConnection * const connection = getPreferredServer(processName, options, cost);
if (connection)
return connection;
}
// there is not a preferred node available, so look for a node which is not preferred in some form
{
ManagerConnection * const connection = getUnpreferredServer(cost);
if (connection)
return connection;
}
// there is not a non-preferred node available, so look for any node other than the command node;
// If more than one node qualifies, we want to choose the one who currently has the lowest load
{
for (std::vector<ServerEntry>::iterator i = s_serverList.begin(); i != s_serverList.end(); ++i)
{
ServerEntry &e = *i;
if ((e.m_label != s_masterNodeLabel) && (e.hasAvailableLoad(cost)))
{
// s_serverList is ordered by load, so this will
// return the available node with the lowest load
return e.m_connection;
}
}
WARNING(true, ("No hosts are available to spawn a process costing %f without exceeding the host's load limit", cost));
}
return 0;
}
// ----------------------------------------------------------------------
ManagerConnection *Locator::getServer(std::string const &label)
{
for (std::vector<ServerEntry>::const_iterator i = s_serverList.begin(); i != s_serverList.end(); ++i)
if (i->m_label == label || i->m_connection->getRemoteAddress() == label)
return i->m_connection;
return 0;
}
// ----------------------------------------------------------------------
float Locator::getServerLoad(std::string const &label)
{
std::vector<ServerEntry>::const_iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if (i != s_serverList.end())
return i->m_load;
return 0.f;
}
// ----------------------------------------------------------------------
float Locator::getServerMaximumLoad(std::string const &label)
{
std::vector<ServerEntry>::const_iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if (i != s_serverList.end())
return i->m_maximumLoad;
// see if there is a maximum load specified for this particular node
char key[128];
snprintf(key, sizeof(key)-1, "maximumLoad.%s", label.c_str());
key[sizeof(key)-1] = '\0';
return getConfigSetting("TaskManager", key, ConfigTaskManager::getMaximumLoad());
}
// ----------------------------------------------------------------------
void Locator::incrementMyLoad(float amount)
{
s_myLoad += amount;
std::sort(s_serverList.begin(), s_serverList.end());
}
// ----------------------------------------------------------------------
void Locator::decrementMyLoad(float amount)
{
s_myLoad -= amount;
if (s_myLoad < 0.0f)
s_myLoad = 0.0f;
std::sort(s_serverList.begin(), s_serverList.end());
updateAllLoads(-amount);
}
// ----------------------------------------------------------------------
void Locator::incrementServerLoad(std::string const &label, float amount)
{
std::vector<ServerEntry>::iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if (i != s_serverList.end())
{
i->m_load += amount;
std::sort(s_serverList.begin(), s_serverList.end());
}
}
// ----------------------------------------------------------------------
void Locator::decrementServerLoad(std::string const &label, float amount)
{
std::vector<ServerEntry>::iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if (i != s_serverList.end())
{
i->m_load -= amount;
if (i->m_load < 0.0f)
{
DEBUG_WARNING(true, ("%s dropped less than 0", label.c_str()));
i->m_load = 0.0f;
}
std::sort(s_serverList.begin(), s_serverList.end());
}
}
// ----------------------------------------------------------------------
float Locator::getMyLoad()
{
return s_myLoad;
}
// ----------------------------------------------------------------------
float Locator::getMyMaximumLoad()
{
static float myMaximumLoad = -1.0f;
// get the maximum load for this particular node
if (myMaximumLoad <= 0.0f)
{
// see if there is a maximum load specified for this particular node
char key[128];
snprintf(key, sizeof(key)-1, "maximumLoad.%s", TaskManager::getNodeLabel().c_str());
key[sizeof(key)-1] = '\0';
myMaximumLoad = getConfigSetting("TaskManager", key, ConfigTaskManager::getMaximumLoad());
}
return myMaximumLoad;
}
// ----------------------------------------------------------------------
void Locator::opened(std::string const &label, ManagerConnection *newConnection)
{
if (newConnection)
{
std::vector<ServerEntry>::const_iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if (i == s_serverList.end())
{
ServerEntry s(newConnection, label, 0.0f);
s_serverList.push_back(s);
std::sort(s_serverList.begin(), s_serverList.end());
IGNORE_RETURN(s_closedConnections.erase(label));
LOG("TaskManagerConnect", ("Connection with remote task manager %s established with label %s, maximum load %f", newConnection->getRemoteAddress().c_str(), label.c_str(), s.m_maximumLoad));
}
else
{
WARNING_STRICT_FATAL(true, ("Tried to add %s on %s to server list but it already exsists", label.c_str(), newConnection->getRemoteAddress().c_str()));
}
DEBUG_REPORT_LOG(true, ("Connection with remote task manager %s established with label %s\n", newConnection->getRemoteAddress().c_str(), label.c_str()));
TaskManager::runSpawnRequestQueue();
}
else
WARNING_STRICT_FATAL(true, ("Passed null connection to Locator::opened"));
}
// ----------------------------------------------------------------------
void Locator::updateServerLoad(std::string const &label, float load)
{
std::vector<ServerEntry>::iterator i = std::find(s_serverList.begin(), s_serverList.end(), label);
if(i != s_serverList.end())
{
i->m_load += load;
std::sort(s_serverList.begin(), s_serverList.end());
LOG("TaskManager", ("updateServerLoad(%s, %f)", label.c_str(), load));
}
else
{
DEBUG_WARNING(true, ("Told to update load on %s which didn't exist\n", label.c_str()));
}
TaskManager::runSpawnRequestQueue();
}
// ----------------------------------------------------------------------
void Locator::updateAllLoads(float delta)
{
if (!s_serverList.empty())
{
TaskUtilization const util(TaskUtilization::SYSTEM_AVG, delta);
sendToAllTaskManagers(util);
}
}
// ----------------------------------------------------------------------
std::map<std::string, std::string> const & Locator::getClosedConnections()
{
return s_closedConnections;
}
// ----------------------------------------------------------------------
void Locator::sendToAllTaskManagers(GameNetworkMessage const &msg)
{
if (!s_serverList.empty())
for (std::vector<ServerEntry>::const_iterator i = s_serverList.begin(); i != s_serverList.end(); ++i)
i->m_connection->send(msg);
}
// ----------------------------------------------------------------------
void LocatorNamespace::addPreferredNode(std::string const &preferredNodeSpec)
{
// preferredNodeSpec is "nodeLabel:processName:option=value:option=value:..."
PreferredNode n;
std::string::size_type lastPos = 0;
std::string::size_type pos;
pos = preferredNodeSpec.find(':', lastPos);
n.m_nodeLabel = preferredNodeSpec.substr(lastPos, pos-lastPos);
lastPos = pos == std::string::npos ? preferredNodeSpec.size() : pos+1;
pos = preferredNodeSpec.find(':', lastPos);
n.m_processName = preferredNodeSpec.substr(lastPos, pos-lastPos);
lastPos = pos == std::string::npos ? preferredNodeSpec.size() : pos+1;
while (lastPos != std::string::npos)
{
pos = preferredNodeSpec.find(':', lastPos);
n.m_nodeOptions.push_back(preferredNodeSpec.substr(lastPos, pos-lastPos));
lastPos = pos == std::string::npos ? std::string::npos : pos+1;
}
if (!n.m_nodeLabel.empty() && !n.m_processName.empty())
s_preferredNodes.push_back(n);
}
// ======================================================================
@@ -0,0 +1,46 @@
// ======================================================================
//
// Locator.h
//
// Copyright 2000-04 Sony Online Entertainment
//
// ======================================================================
#ifndef _INCLUDED_Locator_H
#define _INCLUDED_Locator_H
// ======================================================================
#include <string>
class GameNetworkMessage;
class ManagerConnection;
// ======================================================================
class Locator
{
public:
static void install();
static void closed(std::string const &label, ManagerConnection const *oldConnection);
static ManagerConnection *getBestServer(std::string const &processName, std::string const &options, float cost);
static float getMyLoad();
static float getMyMaximumLoad();
static float getServerLoad(std::string const &label);
static float getServerMaximumLoad(std::string const &label);
static ManagerConnection *getServer(std::string const &label);
static void incrementMyLoad(float amount);
static void incrementServerLoad(std::string const &label, float amount);
static void decrementMyLoad(float amount);
static void decrementServerLoad(std::string const &label, float amount);
static void opened(std::string const &label, ManagerConnection *newConnection);
static void sendToAllTaskManagers(GameNetworkMessage const &msg);
static void updateServerLoad(std::string const &label, float load);
static void updateAllLoads(float delta);
static stdmap<std::string, std::string>::fwd const & getClosedConnections();
};
// ======================================================================
#endif // _INCLUDED_Locator_H
@@ -0,0 +1,225 @@
// ManagerConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "Locator.h"
#include "ManagerConnection.h"
#include "serverNetworkMessages/TaskProcessDiedMessage.h"
#include "serverNetworkMessages/TaskSpawnProcess.h"
#include "serverNetworkMessages/TaskSpawnProcessAck.h"
#include "serverNetworkMessages/TaskUtilization.h"
#include "serverNetworkMessages/TaskConnectionIdMessage.h"
#include "sharedFoundation/CalendarTime.h"
#include "sharedFoundation/Clock.h"
#include "sharedFoundation/FormattedString.h"
#include "sharedFoundation/Scheduler.h"
#include "sharedLog/Log.h"
#include "sharedMessageDispatch/Transceiver.h"
#include "sharedNetwork/NetworkSetupData.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "ConfigTaskManager.h"
#include "TaskConnection.h"
#include "TaskManager.h"
//-----------------------------------------------------------------------
namespace ManagerConnectionNamespace
{
int s_managerConnectionCount = 0;
}
using namespace ManagerConnectionNamespace;
//-----------------------------------------------------------------------
ManagerConnection::ManagerConnection(const std::string & a, const unsigned short p) :
Connection(a,p, NetworkSetupData()),
m_nodeLabel(0),
m_remoteUtilAvg(100000.0f)
{
}
//-----------------------------------------------------------------------
ManagerConnection::ManagerConnection(UdpConnectionMT * u, TcpClient * t) :
Connection(u, t),
m_nodeLabel(0),
m_remoteUtilAvg(100000.0f)
{
}
//-----------------------------------------------------------------------
ManagerConnection::~ManagerConnection()
{
if (m_nodeLabel)
{
Locator::closed(*m_nodeLabel, this);
delete m_nodeLabel;
m_nodeLabel = 0;
}
}
//-----------------------------------------------------------------------
void ManagerConnection::onConnectionClosed()
{
DEBUG_REPORT_LOG(true, ("Manager connection %s closed\n", getRemoteAddress().c_str()));
TaskManager::retryConnection(this);
if (m_nodeLabel)
{
Locator::closed(*m_nodeLabel, this);
delete m_nodeLabel;
m_nodeLabel = 0;
}
s_managerConnectionCount--;
}
//-----------------------------------------------------------------------
void ManagerConnection::onConnectionOpened()
{
DEBUG_REPORT_LOG(true, ("Manager connection opened\n"));
TaskConnectionIdMessage id(TaskConnectionIdMessage::TaskManager, TaskManager::getNodeLabel(), ConfigTaskManager::getClusterName());
send(id);
s_managerConnectionCount++;
}
//-----------------------------------------------------------------------
void ManagerConnection::onReceive(const Archive::ByteStream & message)
{
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
r = message.begin();
if (m.isType("SystemTimeCheck"))
{
long const currentTime = static_cast<long>(::time(NULL));
GenericValueTypeMessage<std::pair<std::string, long > > msg(r);
if (TaskManager::getNodeLabel() == "node0")
{
if ((std::max(currentTime, msg.getValue().second) - std::min(currentTime, msg.getValue().second)) > ConfigTaskManager::getMaximumClockDriftToleranceSeconds())
{
LOG("CustomerService", ("system_clock_mismatch:System clock mismatch (%d seconds) by more than %d seconds: master TaskManager epoch (%ld), remote TaskManager %s (%s) epoch (%ld)", (std::max(currentTime, msg.getValue().second) - std::min(currentTime, msg.getValue().second)), ConfigTaskManager::getMaximumClockDriftToleranceSeconds(), currentTime, msg.getValue().first.c_str(), getRemoteAddress().c_str(), msg.getValue().second));
// tell CentralServer about the system clock mismatch so it can report an alert to SOEMon
GenericValueTypeMessage<std::string> systemTimeMismatchMessage("SystemTimeMismatchNotification",
FormattedString<1024>().sprintf("%s: %s (%s) is off by %ld seconds", CalendarTime::convertEpochToTimeStringLocal(static_cast<time_t>(currentTime)).c_str(), msg.getValue().first.c_str(), getRemoteAddress().c_str(), (std::max(currentTime, msg.getValue().second) - std::min(currentTime, msg.getValue().second))));
TaskManager::sendToCentralServer(systemTimeMismatchMessage);
}
}
}
else if (m.isType("TaskConnectionIdMessage"))
{
static long const clockDriftFatalTimePeriod = static_cast<long>(TaskManager::getStartTime()) + ConfigTaskManager::getClockDriftFatalIntervalSeconds();
long const currentTime = static_cast<long>(::time(NULL));
TaskConnectionIdMessage t(r);
WARNING_STRICT_FATAL(t.getServerType() != TaskConnectionIdMessage::TaskManager,
("ManagerConnection received wrong type identifier"));
WARNING_STRICT_FATAL(m_nodeLabel, ("Received new taskconnectionIdMessage with an already named connection"));
FATAL((ConfigTaskManager::getVerifyClusterName() && (TaskManager::getNodeLabel() == "node0") && (t.getServerType() == TaskConnectionIdMessage::TaskManager) && (t.getClusterName() != std::string(ConfigTaskManager::getClusterName()))), ("Remote TaskManager %s (%s) reported cluster name (%s) that is different from my cluster name (%s)", t.getCommandLine().c_str(), getRemoteAddress().c_str(), t.getClusterName().c_str(), ConfigTaskManager::getClusterName()));
// don't allow cluster to start if the system clock across the boxes are out of sync
bool remoteSystemClockInSync = true;
if (TaskManager::getNodeLabel() == "node0")
{
if ((std::max(currentTime, t.getCurrentEpochTime()) - std::min(currentTime, t.getCurrentEpochTime())) > ConfigTaskManager::getMaximumClockDriftToleranceSeconds())
{
remoteSystemClockInSync = false;
// don't bring down the cluster if we lost a box and when the box is
// restarted, its system clock is out of sync; just ignore that
// TaskManager, and send it a message to terminate itself
if (currentTime <= clockDriftFatalTimePeriod)
{
FATAL(true, ("System clock mismatch (%d seconds) by more than %d seconds: master TaskManager epoch (%ld), remote TaskManager %s (%s) epoch (%ld)", (std::max(currentTime, t.getCurrentEpochTime()) - std::min(currentTime, t.getCurrentEpochTime())), ConfigTaskManager::getMaximumClockDriftToleranceSeconds(), currentTime, t.getCommandLine().c_str(), getRemoteAddress().c_str(), t.getCurrentEpochTime()));
}
else
{
LOG("CustomerService", ("system_clock_mismatch:System clock mismatch (%d seconds) by more than %d seconds: master TaskManager epoch (%ld), remote TaskManager %s (%s) epoch (%ld). Telling remote TaskManager to terminate.", (std::max(currentTime, t.getCurrentEpochTime()) - std::min(currentTime, t.getCurrentEpochTime())), ConfigTaskManager::getMaximumClockDriftToleranceSeconds(), currentTime, t.getCommandLine().c_str(), getRemoteAddress().c_str(), t.getCurrentEpochTime()));
GenericValueTypeMessage<std::pair<std::string, std::pair<long, long> > > systemTimeMismatchMessage("SystemTimeMismatchMessage", std::make_pair(TaskManager::getNodeLabel(), std::make_pair(static_cast<long>(currentTime), t.getCurrentEpochTime())));
send(systemTimeMismatchMessage);
}
}
}
if (remoteSystemClockInSync)
{
m_nodeLabel = new std::string(t.getCommandLine());
Locator::opened(*m_nodeLabel, this);
TaskManager::resendUnacknowledgedSpawnRequests(this, *m_nodeLabel);
}
}
else if (m.isType("SystemTimeMismatchMessage"))
{
GenericValueTypeMessage<std::pair<std::string, std::pair<long, long> > > msg(r);
FATAL((msg.getValue().first == "node0"), ("System clock mismatch (%d seconds) by more than %d seconds: master TaskManager epoch (%ld), self epoch (%ld)", (std::max(msg.getValue().second.first, msg.getValue().second.second) - std::min(msg.getValue().second.first, msg.getValue().second.second)), ConfigTaskManager::getMaximumClockDriftToleranceSeconds(), msg.getValue().second.first, msg.getValue().second.second));
}
else if(m.isType("TaskSpawnProcess"))
{
TaskSpawnProcess s(r);
if (TaskManager::startServer(s.getProcessName(), s.getOptions(), s.getTargetHostAddress(), s.getSpawnDelay()) == 0)
{
DEBUG_REPORT_LOG(true, ("Failed to spawn %s on this node\n", s.getProcessName().c_str()));
//send fail message back
}
else
{
TaskSpawnProcessAck ack(s.getTransactionId());
send(ack);
}
}
else if(m.isType("TaskUtilization"))
{
TaskUtilization util(r);
switch(util.getUtilType())
{
case TaskUtilization::SYSTEM_AVG:
{
if (m_nodeLabel)
{
m_remoteUtilAvg = util.getUtilAmount();
Locator::updateServerLoad(*m_nodeLabel, m_remoteUtilAvg);
}
}
break;
default:
break;
}
}
else if(m.isType("TaskProcessDiedMessage"))
{
TaskProcessDiedMessage died(r);
TaskManager::sendToCentralServer(died);
}
else if(m.isType("TaskSpawnProcessAck"))
{
TaskSpawnProcessAck ack(r);
TaskManager::removePendingSpawnProcessAck(ack.getTransactionId());
}
}
//-----------------------------------------------------------------------
void ManagerConnection::send(const GameNetworkMessage & message)
{
Archive::ByteStream b;
message.pack(b);
Connection::send(b, true);
}
//-----------------------------------------------------------------------
int ManagerConnection::getConnectionCount()
{
return s_managerConnectionCount;
}
//-----------------------------------------------------------------------
@@ -0,0 +1,51 @@
// ManagerConnection.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_ManagerConnection_H
#define _INCLUDED_ManagerConnection_H
//-----------------------------------------------------------------------
#include "sharedMessageDispatch/Transceiver.h"
#include "TaskHandler.h"
#include "sharedNetwork/Connection.h"
class GameNetworkMessage;
class TaskConnection;
//-----------------------------------------------------------------------
class ManagerConnection : public Connection
{
public:
ManagerConnection(const std::string & remoteAddres, const unsigned short remotePort);
ManagerConnection(UdpConnectionMT*, TcpClient *);
~ManagerConnection();
static int getConnectionCount ();
const std::string* getNodeLabel() const;
virtual void onConnectionClosed ();
virtual void onConnectionOpened ();
virtual void onReceive (const Archive::ByteStream & message);
void send(const GameNetworkMessage & message);
private:
ManagerConnection & operator = (const ManagerConnection & rhs);
ManagerConnection(const ManagerConnection & source);
ManagerConnection();
private:
std::string *m_nodeLabel;
float m_remoteUtilAvg;
};
//-----------------------------------------------------------------------
inline const std::string* ManagerConnection::getNodeLabel() const
{
return m_nodeLabel;
}
//-----------------------------------------------------------------------
#endif // _INCLUDED_ManagerConnection_H
@@ -0,0 +1,87 @@
// MetricsServerConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "MetricsServerConnection.h"
#include "sharedFoundation/Clock.h"
#include "sharedMessageDispatch/Transceiver.h"
#include "TaskConnection.h"
#include "TaskManager.h"
//-----------------------------------------------------------------------
MetricsServerConnection::MetricsServerConnection(TaskConnection * c, const std::string & n) :
TaskHandler(),
callback(),
commandLine(n),
connected(true),
connection(c),
lastSpawnTime(Clock::timeMs())
{
callback.connect(c->getTransceiverClosed(), *this, &MetricsServerConnection::closed); //lint !e1025 !e1703 !e1514 !e64
callback.connect(*this, &MetricsServerConnection::onProcessKilled); //lint !e1025 !e1703 !e1514 !e64 !e1058 !e118
}
//-----------------------------------------------------------------------
MetricsServerConnection::~MetricsServerConnection()
{
connection = 0;
}
//-----------------------------------------------------------------------
void MetricsServerConnection::closed(const Closed &)
{
if(connected)
{
ProcessAborted a;
a.commandLine = commandLine;
a.hostName = NetworkHandler::getHostName();
MessageDispatch::Transceiver<const ProcessAborted &> b;
b.emitMessage(a);
unsigned long t = Clock::timeMs();
if(t - lastSpawnTime > 5000) // stop spawning if it bombs immediately
{
lastSpawnTime = t;
// need to restart it!
// IGNORE_RETURN(TaskManager::startServer("MetricsServer", "", "local"));
}
else
{
// emit the killed message
ProcessKilled k;
k.commandLine = a.commandLine;
k.hostName = a.hostName;
MessageDispatch::Transceiver<const ProcessKilled &> pk;
pk.emitMessage(k);
}
connected = false;
}
}
//-----------------------------------------------------------------------
void MetricsServerConnection::onProcessKilled(const ProcessKilled & k)
{
if(k.commandLine == commandLine)
lastSpawnTime = Clock::timeMs(); // force it to stay dead
}
//-----------------------------------------------------------------------
void MetricsServerConnection::receive(const Archive::ByteStream & )
{
#if 0
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
#endif
}
//-----------------------------------------------------------------------
@@ -0,0 +1,42 @@
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_MetricsServerConnection_H
#define _INCLUDED_MetricsServerConnection_H
//-----------------------------------------------------------------------
#include "sharedMessageDispatch/Transceiver.h"
#include "TaskHandler.h"
class TaskConnection;
struct Closed;
//-----------------------------------------------------------------------
class MetricsServerConnection : public TaskHandler
{
public:
MetricsServerConnection(TaskConnection * newConnection, const std::string & commandLine);
~MetricsServerConnection();
void closed(const Closed &);
void receive(const Archive::ByteStream & message);
private:
MetricsServerConnection();
MetricsServerConnection & operator = (const MetricsServerConnection & rhs);
MetricsServerConnection(const MetricsServerConnection & source);
void onProcessKilled(const struct ProcessKilled &);
private:
MessageDispatch::Callback callback;
std::string commandLine;
bool connected;
TaskConnection * connection;
unsigned long lastSpawnTime;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_MetricsServerConnection_H
@@ -0,0 +1,65 @@
// PlanetConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "PlanetConnection.h"
#include "serverNetworkMessages/TaskSpawnProcess.h"
#include "sharedMessageDispatch/Transceiver.h"
#include "TaskConnection.h"
#include "TaskManager.h"
//-----------------------------------------------------------------------
PlanetConnection::PlanetConnection(TaskConnection * c) :
TaskHandler(),
connection(c)
{
}
//-----------------------------------------------------------------------
PlanetConnection::PlanetConnection(const PlanetConnection &)
{
connection = 0;
}
//-----------------------------------------------------------------------
PlanetConnection::~PlanetConnection()
{
}
//-----------------------------------------------------------------------
PlanetConnection & PlanetConnection::operator = (const PlanetConnection & rhs)
{
if(this != &rhs)
{
// make assignments if right hand side is not this instance
}
return *this;
}
//-----------------------------------------------------------------------
void PlanetConnection::receive(const Archive::ByteStream & message)
{
static const std::string localName = NetworkHandler::getHostName();
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
r = message.begin();
if(m.isType("TaskSpawnProcess"))
{
TaskSpawnProcess s(r);
TaskManager::startServer(s.getProcessName(), s.getOptions(), s.getTargetHostAddress(), s.getSpawnDelay());
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,32 @@
// PlanetConnection.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
#ifndef _INCLUDED_PlanetConnection_H
#define _INCLUDED_PlanetConnection_H
//-----------------------------------------------------------------------
#include "TaskHandler.h"
class TaskConnection;
//-----------------------------------------------------------------------
class PlanetConnection : public TaskHandler
{
public:
PlanetConnection(TaskConnection * connection);
~PlanetConnection();
void receive(const Archive::ByteStream & message);
private:
PlanetConnection & operator = (const PlanetConnection & rhs);
PlanetConnection(const PlanetConnection & source);
TaskConnection * connection;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_PlanetConnection_H
@@ -0,0 +1,26 @@
#ifndef _PROCESS_SPAWNER_H
#define _PROCESS_SPAWNER_H
#include <string>
#include <vector>
class ProcessSpawner
{
public:
static uint32 execute(const std::string & commandLine, const std::vector<std::string> & parameters);
static uint32 execute(const std::string & commandLine);
static void forceCore(const unsigned long pid);
static bool isProcessActive(uint32 pid);
static void kill(uint32 pid);
static uint32 postfixCounter;
static uint32 prefix;
private:
ProcessSpawner();
~ProcessSpawner();
ProcessSpawner(const ProcessSpawner&);
ProcessSpawner& operator= (const ProcessSpawner&);
};
//-----------------------------------------------------------------------
#endif // _PROCESS_SPAWNER_H
@@ -0,0 +1,225 @@
// TaskConnection.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "CentralConnection.h"
#include "ConfigTaskManager.h"
#include "DatabaseConnection.h"
#include "Locator.h"
#include "GameConnection.h"
#include "ManagerConnection.h"
#include "MetricsServerConnection.h"
#include "PlanetConnection.h"
#include "TaskConnection.h"
#include "TaskManager.h"
#include "serverNetworkMessages/ExcommunicateGameServerMessage.h"
#include "serverNetworkMessages/TaskConnectionIdMessage.h"
#include "serverNetworkMessages/TaskKillProcess.h"
#include "sharedNetwork/NetworkSetupData.h"
//-----------------------------------------------------------------------
TaskConnection::TaskConnection(const std::string & a, const unsigned short p) :
Connection(a, p, NetworkSetupData()),
closed(),
failed(),
identified(),
opened(),
overflowing(),
receiveMessage(),
reset(),
handler(0)
{
}
//-----------------------------------------------------------------------
TaskConnection::TaskConnection(UdpConnectionMT * u, TcpClient * t) :
Connection(u, t),
closed(),
failed(),
identified(),
opened(),
overflowing(),
receiveMessage(),
reset(),
handler(0)
{
}
//-----------------------------------------------------------------------
TaskConnection::~TaskConnection()
{
delete handler;
}
//-----------------------------------------------------------------------
void TaskConnection::onConnectionClosed()
{
static Closed msg;
closed.emitMessage(msg); //lint !e738 Symbol 'msg' not explicitly initialized
}
//-----------------------------------------------------------------------
void TaskConnection::onConnectionOpened()
{
DEBUG_REPORT_LOG(true, ("Task Connection opened %s\n", getRemoteAddress().c_str()));
static Opened msg;
opened.emitMessage(msg); //lint !e738 Symbol 'msg' not explicitly initialized
}
//-----------------------------------------------------------------------
void TaskConnection::onConnectionOverflowing(const unsigned int bytesPending)
{
static Overflowing msg;
msg.bytesPending = bytesPending;
overflowing.emitMessage(msg);
}
//-----------------------------------------------------------------------
void TaskConnection::onReceive(const Archive::ByteStream & message)
{
static Receive msg;
if(handler)
handler->receive(message);
Archive::ReadIterator r(message);
GameNetworkMessage m(r);
if(m.isType("TaskConnectionIdMessage"))
{
r = message.begin();
TaskConnectionIdMessage t(r);
FATAL((ConfigTaskManager::getVerifyClusterName() && (TaskManager::getNodeLabel() == "node0") && (t.getServerType() == TaskConnectionIdMessage::TaskManager) && (t.getClusterName() != std::string(ConfigTaskManager::getClusterName()))), ("Remote TaskManager %s (%s) reported cluster name (%s) that is different from my cluster name (%s)", t.getCommandLine().c_str(), getRemoteAddress().c_str(), t.getClusterName().c_str(), ConfigTaskManager::getClusterName()));
Identified i = {this, t.getServerType() };
identified.emitMessage(i);
switch(i.id)
{
case TaskConnectionIdMessage::Central:
{
REPORT_LOG(true, ("New Central Server connection active\n"));
handler = new CentralConnection(this, t.getCommandLine());
TaskManager::setCentralConnection(this);
}
break;
case TaskConnectionIdMessage::Game:
{
REPORT_LOG(true, ("New Game Server connection active\n"));
handler = new GameConnection(this);
}
break;
case TaskConnectionIdMessage::Database:
{
REPORT_LOG(true, ("New Database Server connection active\n"));
handler = new DatabaseConnection();
}
break;
case TaskConnectionIdMessage::Metrics:
{
REPORT_LOG(true, ("New Metrics Server connection active\n"));
handler = new MetricsServerConnection(this, t.getCommandLine());
}
break;
case TaskConnectionIdMessage::Planet:
{
REPORT_LOG(true, ("New Planet Server connection active\n"));
handler = new PlanetConnection(this);
}
break;
default:
WARNING_STRICT_FATAL(true, ("Unknown id (%d) received on task connection", i.id));
break;
}
}
else if(m.isType("ExcommunicateGameServerMessage"))
{
r = message.begin();
ExcommunicateGameServerMessage ex(r);
TaskKillProcess k(ex.getHostName(), ex.getProcessId(), true);
TaskManager::killProcess(k);
// broadcast to other task managers
Locator::sendToAllTaskManagers(k);
}
else if(m.isType("TaskKillProcess"))
{
r = message.begin();
TaskKillProcess k(r);
TaskManager::killProcess(k);
}
msg.message = &message;
receiveMessage.emitMessage(msg);
}
//-----------------------------------------------------------------------
void TaskConnection::send(const GameNetworkMessage & message)
{
Archive::ByteStream b;
message.pack(b);
Connection::send(b, true);
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Closed &> & TaskConnection::getTransceiverClosed()
{
return closed; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Failed &> & TaskConnection::getTransceiverFailed()
{
return failed; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Identified &> & TaskConnection::getTransceiverIdentified()
{
return identified; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Opened &> & TaskConnection::getTransceiverOpened()
{
return opened; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Overflowing &> & TaskConnection::getTransceiverOverflowing()
{
return overflowing; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Receive &> & TaskConnection::getTransceiverReceive()
{
return receiveMessage; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
MessageDispatch::Transceiver<const Reset &> & TaskConnection::getTransceiverReset()
{
return reset; //lint !e1536 Exposing low access member
}
//-----------------------------------------------------------------------
@@ -0,0 +1,75 @@
// TaskConnection.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_TaskConnection_H
#define _INCLUDED_TaskConnection_H
//-----------------------------------------------------------------------
#include <algorithm>
#include "sharedMessageDispatch/Transceiver.h"
#include "sharedNetwork/Connection.h"
namespace Archive
{
class ByteStream;
}
class GameNetworkMessage;
class TaskConnection;
class TaskHandler;
//-----------------------------------------------------------------------
struct Closed {};
struct Failed {};
struct Identified {TaskConnection * connection; unsigned char id;};
struct Opened {};
struct Overflowing {unsigned int bytesPending;};
struct Receive {const Archive::ByteStream * message;};
struct Reset {};
class TaskConnection : public Connection
{
public:
public:
TaskConnection(const std::string & remoteAddress, const unsigned short remotePort);
TaskConnection(UdpConnectionMT *, TcpClient *);
~TaskConnection();
static int getConnectionCount ();
virtual void onConnectionClosed ();
virtual void onConnectionOpened ();
virtual void onConnectionOverflowing (const unsigned int bytesPending);
virtual void onReceive (const Archive::ByteStream & message);
void send (const GameNetworkMessage & message); //lint !e1411 Member with different signature hides virtual member 'Connection::send(const Archive::ByteStream &, bool) const // jrandall how can it hide the virtual if the signature differs?
MessageDispatch::Transceiver<const Closed &> & getTransceiverClosed ();
MessageDispatch::Transceiver<const Failed &> & getTransceiverFailed ();
MessageDispatch::Transceiver<const Identified &> & getTransceiverIdentified ();
MessageDispatch::Transceiver<const Opened &> & getTransceiverOpened ();
MessageDispatch::Transceiver<const Overflowing &> & getTransceiverOverflowing ();
MessageDispatch::Transceiver<const Receive &> & getTransceiverReceive ();
MessageDispatch::Transceiver<const Reset &> & getTransceiverReset ();
private: // capabilities / emissions
MessageDispatch::Transceiver<const Closed &> closed;
MessageDispatch::Transceiver<const Failed &> failed;
MessageDispatch::Transceiver<const Identified &> identified;
MessageDispatch::Transceiver<const Opened &> opened;
MessageDispatch::Transceiver<const Overflowing &> overflowing;
MessageDispatch::Transceiver<const Receive &> receiveMessage;
MessageDispatch::Transceiver<const Reset &> reset;
private:
TaskConnection & operator = (const TaskConnection & rhs);
TaskConnection(const TaskConnection & source);
private:
TaskHandler * handler;
}; //lint !e1712 default constructor not defined for class 'TaskConnection'
//-----------------------------------------------------------------------
#endif // _INCLUDED_TaskConnection_H
@@ -0,0 +1,41 @@
// TaskHandler.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstTaskManager.h"
#include "TaskHandler.h"
//-----------------------------------------------------------------------
TaskHandler::TaskHandler()
{
}
//-----------------------------------------------------------------------
TaskHandler::TaskHandler(const TaskHandler &)
{
}
//-----------------------------------------------------------------------
TaskHandler::~TaskHandler()
{
}
//-----------------------------------------------------------------------
TaskHandler & TaskHandler::operator = (const TaskHandler & rhs)
{
if(this != &rhs)
{
// make assignments if right hand side is not this instance
}
return *this;
}
//-----------------------------------------------------------------------
@@ -0,0 +1,33 @@
// TaskHandler.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_TaskHandler_H
#define _INCLUDED_TaskHandler_H
//-----------------------------------------------------------------------
namespace Archive
{
class ByteStream;
}
//-----------------------------------------------------------------------
class TaskHandler
{
public:
TaskHandler();
virtual ~TaskHandler() = 0;
virtual void receive(const Archive::ByteStream & message) = 0;
private:
TaskHandler & operator = (const TaskHandler & rhs);
TaskHandler(const TaskHandler & source);
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_TaskHandler_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,179 @@
// TaskManager.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_TaskManager_H
#define _INCLUDED_TaskManager_H
#include <map>
#include <string>
#include <set>
#include <vector>
//-----------------------------------------------------------------------
class Connection;
class ConsoleConnection;
class GameNetworkMessage;
class LoginConnection;
class Service;
class ManagerConnection;
class TaskConnection;
class TaskKillProcess;
class TaskManagerSysInfo;
//-----------------------------------------------------------------------
struct ProcessKilled
{
std::string commandLine;
std::string hostName;
};
//-----------------------------------------------------------------------
struct ProcessAborted
{
std::string commandLine;
std::string hostName;
};
//-----------------------------------------------------------------------
struct ProcessStarted
{
unsigned long pid;
std::string commandLine;
std::string hostName;
};
//-----------------------------------------------------------------------
struct RequestProcessKill
{
std::string commandLine;
std::string hostName;
unsigned long pid;
};
//-----------------------------------------------------------------------
struct RequestProcessStart
{
std::string commandLine;
std::string hostName;
};
//-----------------------------------------------------------------------
struct ProcessEntry
{
std::string processName;
std::string targetHost;
std::string executable;
std::string options;
};
//-----------------------------------------------------------------------
class TaskManager
{
public:
typedef unsigned int SpawnDelaySeconds;
TaskManager();
~TaskManager();
static std::string executeCommand (const std::string & command);
static const float getLoadAverage ();
static const std::string & getNodeLabel();
static time_t getStartTime();
static void killProcess (const TaskKillProcess &);
static void retryConnection (ManagerConnection const *connection);
static void sendToCentralServer (const GameNetworkMessage & msg);
static void setCentralConnection (TaskConnection * connection);
static void onDatabaseIdle (bool isIdle);
static void onPreloadFinished ();
static void runSpawnRequestQueue ();
static unsigned long startServer (const std::string & processName, const std::string & options, const std::string& hostName, SpawnDelaySeconds spawnDelay);
static void stopCluster ();
static void resendUnacknowledgedSpawnRequests (Connection * connection, const std::string & nodeLabel);
static void removePendingSpawnProcessAck (int transactionId);
static void install ();
static void remove ();
static void run ();
static void update ();
static const std::set<std::pair< std::string, unsigned long> > & getLocalServers();
static const std::map<std::string, std::pair<std::string, unsigned long> > & getRemoteServers();
static void addToGameConnections(int x);
static int getNumGameConnections();
private:
TaskManager & operator = (const TaskManager & rhs);
TaskManager(const TaskManager & source);
static TaskManager & instance();
void processRcFile();
void processEnvironmentVariables();
void setupNodeList();
static unsigned long startServerLocal(const ProcessEntry & processEntry, const std::string & options);
static void startCluster();
private:
struct NodeEntry
{
NodeEntry(const std::string &, const std::string & , int);
bool operator==(const NodeEntry &) const;
bool operator==(const std::string & address) const;
std::string m_address;
std::string m_nodeLabel;
int m_nodeNumber;
};
std::map<std::string, ProcessEntry> m_processEntries;
std::set<std::pair<std::string, unsigned long> > m_localServers;
std::map<std::string, std::pair<std::string, unsigned long> > m_remoteServers;
std::string m_nodeLabel;
time_t const m_startTime;
std::vector<NodeEntry> m_nodeList;
int m_nodeNumber;
std::vector<NodeEntry> m_nodeToConnectToList;
Service * m_managerService;
Service * m_taskService;
Service * m_consoleService;
TaskManagerSysInfo * m_sysInfoSource;
TaskConnection * m_centralConnection;
};
//-----------------------------------------------------------------------
inline const std::set<std::pair<std::string, unsigned long> > & TaskManager::getLocalServers()
{
return instance().m_localServers;
}
//-----------------------------------------------------------------------
inline const std::string& TaskManager::getNodeLabel()
{
return instance().m_nodeLabel;
}
//-----------------------------------------------------------------------
inline time_t TaskManager::getStartTime()
{
return instance().m_startTime;
}
//-----------------------------------------------------------------------
#endif // _INCLUDED_TaskManager_H
@@ -0,0 +1,28 @@
// TaskManagerSysInfo.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_TaskManagerSysInfo_H
#define _INCLUDED_TaskManagerSysInfo_H
#include <list>
//-----------------------------------------------------------------------
class TaskManagerSysInfo
{
public:
TaskManagerSysInfo();
~TaskManagerSysInfo();
void update();
const float getScore () const;
private:
TaskManagerSysInfo & operator = (const TaskManagerSysInfo & rhs);
TaskManagerSysInfo(const TaskManagerSysInfo & source);
std::list<float> averageScore;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_TaskManagerSysInfo_H