mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-28 22:15:49 -04:00
Added TaskManager app
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
|
||||
add_subdirectory(LoginServer)
|
||||
add_subdirectory(TaskManager)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(TaskManager)
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1,116 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
shared/CentralConnection.cpp
|
||||
shared/CentralConnection.h
|
||||
shared/ConfigTaskManager.cpp
|
||||
shared/ConfigTaskManager.h
|
||||
shared/ConsoleConnection.cpp
|
||||
shared/ConsoleConnection.h
|
||||
shared/Console.cpp
|
||||
shared/Console.h
|
||||
shared/ConsoleImplementation.cpp
|
||||
shared/ConsoleImplementation.h
|
||||
shared/DatabaseConnection.cpp
|
||||
shared/DatabaseConnection.h
|
||||
shared/EnvironmentVariable.h
|
||||
shared/FirstTaskManager.cpp
|
||||
shared/FirstTaskManager.h
|
||||
shared/GameConnection.cpp
|
||||
shared/GameConnection.h
|
||||
shared/Locator.cpp
|
||||
shared/Locator.h
|
||||
shared/ManagerConnection.cpp
|
||||
shared/ManagerConnection.h
|
||||
shared/MetricsServerConnection.cpp
|
||||
shared/MetricsServerConnection.h
|
||||
shared/PlanetConnection.cpp
|
||||
shared/PlanetConnection.h
|
||||
shared/ProcessSpawner.h
|
||||
shared/TaskConnection.cpp
|
||||
shared/TaskConnection.h
|
||||
shared/TaskHandler.cpp
|
||||
shared/TaskHandler.h
|
||||
shared/TaskManager.cpp
|
||||
shared/TaskManager.h
|
||||
shared/TaskManagerSysInfo.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/ConsoleInput.cpp
|
||||
win32/EnvironmentVariable.cpp
|
||||
win32/ProcessSpawner.cpp
|
||||
win32/TaskManagerSysInfo.cpp
|
||||
win32/WinMain.cpp
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
linux/ConsoleInput.cpp
|
||||
linux/EnvironmentVariable.cpp
|
||||
linux/main.cpp
|
||||
linux/ProcessSpawner.cpp
|
||||
linux/TaskManagerSysInfo.cpp
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/linux)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCompression/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedThread/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include
|
||||
)
|
||||
|
||||
link_directories(${STLPORT_LIBDIR})
|
||||
|
||||
add_executable(TaskManager
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(TaskManager
|
||||
sharedCompression
|
||||
sharedDebug
|
||||
sharedFile
|
||||
sharedFoundation
|
||||
sharedLog
|
||||
sharedMath
|
||||
sharedMemoryManager
|
||||
sharedMessageDispatch
|
||||
sharedNetwork
|
||||
sharedNetworkMessages
|
||||
sharedRandom
|
||||
sharedSynchronization
|
||||
sharedThread
|
||||
sharedUtility
|
||||
serverNetworkMessages
|
||||
serverUtility
|
||||
archive
|
||||
fileInterface
|
||||
localization
|
||||
localizationArchive
|
||||
unicode
|
||||
unicodeArchive
|
||||
udplibrary
|
||||
${ZLIB_LIBRARY}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(TaskManager mswsock ws2_32)
|
||||
endif()
|
||||
@@ -0,0 +1,58 @@
|
||||
// TaskManager.cpp
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTaskManager.h"
|
||||
#include "Console.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <curses.h>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
struct SetBufferMode
|
||||
{
|
||||
SetBufferMode();
|
||||
~SetBufferMode() {};
|
||||
};
|
||||
|
||||
SetBufferMode::SetBufferMode()
|
||||
{
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const char Console::getNextChar()
|
||||
{
|
||||
static SetBufferMode setBufferMode;
|
||||
char result = 0;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(STDIN_FILENO, &rfds);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int ready = select(1, &rfds, 0, 0, &tv);
|
||||
if(ready)
|
||||
{
|
||||
result = static_cast<char>(getchar());
|
||||
if(result < 1)
|
||||
result = 0;
|
||||
}
|
||||
/*
|
||||
if(_kbhit())
|
||||
result = static_cast<char>(_getche());
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
#include "FirstTaskManager.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
namespace EnvironmentVariable
|
||||
{
|
||||
bool addToEnvironmentVariable(const char* key, const char* value)
|
||||
{
|
||||
bool retval = false;
|
||||
const char* oldValue = getenv(key);
|
||||
if (oldValue)
|
||||
{
|
||||
std::string s(oldValue);
|
||||
s += ":";
|
||||
s += value;
|
||||
|
||||
//Bad things happen if the first character happens to be : (ie from an empty environment string)
|
||||
const char* newValue = s.c_str();
|
||||
if (newValue[0] == ':')
|
||||
++newValue;
|
||||
|
||||
retval = (setenv(key, newValue, 1) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = (setenv(key, value, 0) == 0);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
bool setEnvironmentVariable(const char* key, const char* value)
|
||||
{
|
||||
return (setenv(key, value, 1) == 0);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,167 @@
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "ProcessSpawner.h"
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <wait.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
uint32 ProcessSpawner::prefix;
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool tokenize (const std::string & str, std::vector<std::string> & result)
|
||||
{
|
||||
size_t end_pos = 0;
|
||||
size_t start_pos = 0;
|
||||
|
||||
result.clear ();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (end_pos >= str.size ())
|
||||
break;
|
||||
|
||||
start_pos = str.find_first_not_of (' ', end_pos);
|
||||
|
||||
if (start_pos == str.npos) //lint !e1705
|
||||
break;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if (str [start_pos] == '\"')
|
||||
{
|
||||
if (++start_pos >= str.size ())
|
||||
break;
|
||||
end_pos = str.find_first_of ('\"', start_pos);
|
||||
}
|
||||
else
|
||||
end_pos = str.find_first_of (' ', start_pos);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if (start_pos == end_pos)
|
||||
break;
|
||||
|
||||
if (end_pos == str.npos) //lint !e1705
|
||||
{
|
||||
result.push_back (str.substr (start_pos));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back (str.substr (start_pos, end_pos - start_pos));
|
||||
}
|
||||
++start_pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint32 execute(const char * commandLine, char * const * parameters)
|
||||
{
|
||||
DEBUG_REPORT_LOG(true, ("Now Attempting To Spawn %s\n", commandLine));
|
||||
pid_t p;
|
||||
// fork
|
||||
p = fork();
|
||||
if (p == 0)
|
||||
{
|
||||
// i am child
|
||||
DEBUG_REPORT_LOG(true, ("Now Spawning %s\n", commandLine));
|
||||
|
||||
int result = execv(commandLine, parameters); //lint !e10 Expecting a function (huh?)
|
||||
if (result == -1)
|
||||
{
|
||||
IGNORE_RETURN(perror("execv")); //lint !e10
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
return p; //lint !e732 Loss of sign
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void makeParameters(const std::vector<std::string> & parameters, std::vector<char *> & p)
|
||||
{
|
||||
std::vector<std::string>::const_iterator i;
|
||||
for(i = parameters.begin(); i != parameters.end(); ++i)
|
||||
{
|
||||
char * arg = new char[(*i).length() + 1];
|
||||
strcpy(arg, (*i).c_str()); //lint !e64 !e534
|
||||
p.push_back(arg);
|
||||
}
|
||||
p.push_back(NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void freeParameters(std::vector<char *> & p)
|
||||
{
|
||||
std::vector<char *>::iterator piter;
|
||||
for(piter = p.begin(); piter != p.end(); ++piter)
|
||||
{
|
||||
char * arg = (*piter);
|
||||
delete[] arg;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint32 ProcessSpawner::execute(const std::string & commandLine, const std::vector<std::string> & parameters)
|
||||
{
|
||||
|
||||
std::vector<char *> p;
|
||||
makeParameters(parameters, p);
|
||||
|
||||
std::string c = "./";
|
||||
c += commandLine;
|
||||
uint32 pid = ::execute(c.c_str(), &p[0]);
|
||||
|
||||
freeParameters(p);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint32 ProcessSpawner::execute(const std::string & commandLine)
|
||||
{
|
||||
std::vector<std::string> parameters;
|
||||
IGNORE_RETURN(tokenize(commandLine, parameters));
|
||||
|
||||
std::vector<char *> p;
|
||||
makeParameters(parameters, p);
|
||||
|
||||
uint32 result = ::execute(p[0], &p[0]);
|
||||
|
||||
freeParameters(p);
|
||||
|
||||
return result;
|
||||
}
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ProcessSpawner::isProcessActive(uint32 pid)
|
||||
{
|
||||
pid_t result = waitpid(static_cast<pid_t>(pid), 0, WNOHANG|WUNTRACED);
|
||||
return (result < 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ProcessSpawner::kill(uint32 pid)
|
||||
{
|
||||
IGNORE_RETURN(::kill(static_cast<int>(pid), SIGKILL));
|
||||
int status;
|
||||
IGNORE_RETURN(waitpid(static_cast<int>(pid), &status, 0));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ProcessSpawner::forceCore(const unsigned long pid)
|
||||
{
|
||||
IGNORE_RETURN(::kill(static_cast<int>(pid), SIGABRT));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -0,0 +1,85 @@
|
||||
// TaskManagerSysInfo.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTaskManager.h"
|
||||
#include "TaskManagerSysInfo.h"
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#include "TaskManager.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo::TaskManagerSysInfo() :
|
||||
averageScore()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo::TaskManagerSysInfo(const TaskManagerSysInfo &)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo::~TaskManagerSysInfo()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo & TaskManagerSysInfo::operator = (const TaskManagerSysInfo & rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
{
|
||||
// make assignments if right hand side is not this instance
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const float TaskManagerSysInfo::getScore() const
|
||||
{
|
||||
#if 0
|
||||
//Temporariy remove this since it's not giving us good results
|
||||
FILE * avg = popen("uptime", "r");
|
||||
float a = 0.0f;
|
||||
if(avg)
|
||||
{
|
||||
std::string output;
|
||||
while(!feof(avg))
|
||||
{
|
||||
char buf[1024] = {"\0"};
|
||||
|
||||
fread(buf, sizeof(buf), 1, avg);
|
||||
output += buf;
|
||||
}
|
||||
char formatted[1024] = {"\0"};
|
||||
std::string load = output.substr(output.find("load average:"));
|
||||
sscanf(load.c_str(), "load average: %f", &a);
|
||||
pclose(avg);
|
||||
}
|
||||
return a;
|
||||
#else
|
||||
|
||||
float ret = static_cast<float>(TaskManager::getNumGameConnections());
|
||||
return ret;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TaskManagerSysInfo::update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
#include "ConfigTaskManager.h"
|
||||
#include "TaskManager.h"
|
||||
|
||||
#include "sharedCompression/SetupSharedCompression.h"
|
||||
#include "sharedDebug/SetupSharedDebug.h"
|
||||
#include "sharedFile/SetupSharedFile.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
|
||||
#include "sharedRandom/SetupSharedRandom.h"
|
||||
#include "sharedThread/SetupSharedThread.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
SetupSharedThread::install();
|
||||
SetupSharedDebug::install(1024);
|
||||
|
||||
//-- setup foundation
|
||||
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
|
||||
setupFoundationData.lpCmdLine = ConvertCommandLine(argc,argv);
|
||||
setupFoundationData.configFile = "taskmanager.cfg";
|
||||
SetupSharedFoundation::install (setupFoundationData);
|
||||
|
||||
SetupSharedCompression::install();
|
||||
SetupSharedFile::install(false);
|
||||
SetupSharedNetworkMessages::install();
|
||||
SetupSharedRandom::install(static_cast<uint32>(time(NULL))); //lint !e1924 !e64 // NULL is a C-Style cast?
|
||||
|
||||
Os::setProgramName("TaskManager");
|
||||
//setup the server
|
||||
ConfigTaskManager::install();
|
||||
|
||||
//-- run game
|
||||
TaskManager::install();
|
||||
TaskManager::run();
|
||||
TaskManager::remove();
|
||||
SetupSharedFoundation::remove();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,22 @@
|
||||
// ConsoleInput.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTaskManager.h"
|
||||
#include "Console.h"
|
||||
#include <conio.h>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const char Console::getNextChar()
|
||||
{
|
||||
char result = 0;
|
||||
if(_kbhit())
|
||||
result = static_cast<char>(_getche());
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "FirstTaskManager.h"
|
||||
|
||||
namespace EnvironmentVariable
|
||||
{
|
||||
bool addToEnvironmentVariable(const char* key, const char* value)
|
||||
{
|
||||
bool retval = false;
|
||||
char oldValue[256];
|
||||
DWORD tmp = GetEnvironmentVariable(key, oldValue, sizeof(oldValue));
|
||||
if (tmp != 0)
|
||||
{
|
||||
std::string s(oldValue);
|
||||
s += ";";
|
||||
s += value;
|
||||
|
||||
//Bad things happen if the first character happens to be ; (ie from an empty environment string)
|
||||
const char* newValue = s.c_str();
|
||||
if (newValue[0] == ';')
|
||||
++newValue;
|
||||
|
||||
retval = (SetEnvironmentVariable(key, newValue) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = (SetEnvironmentVariable(key, value) != 0);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
bool setEnvironmentVariable(const char* key, const char* value)
|
||||
{
|
||||
return (SetEnvironmentVariable(key, value) != 0);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,153 @@
|
||||
#include "FirstTaskManager.h"
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "ProcessSpawner.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "TaskManager.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
uint32 ProcessSpawner::prefix;
|
||||
std::map<uint32, HANDLE> procById;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool tokenize (const std::string & str, std::vector<std::string> & result)
|
||||
{
|
||||
size_t end_pos = 0;
|
||||
size_t start_pos = 0;
|
||||
|
||||
result.clear ();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (end_pos >= str.size ())
|
||||
break;
|
||||
|
||||
start_pos = str.find_first_not_of (' ', end_pos);
|
||||
|
||||
if (start_pos == str.npos)
|
||||
break;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if (str [start_pos] == '\"')
|
||||
{
|
||||
if (++start_pos >= str.size ())
|
||||
break;
|
||||
end_pos = str.find_first_of ('\"', start_pos);
|
||||
}
|
||||
else
|
||||
end_pos = str.find_first_of (' ', start_pos);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if (start_pos == end_pos)
|
||||
break;
|
||||
|
||||
if (end_pos == str.npos)
|
||||
{
|
||||
result.push_back (str.substr (start_pos));
|
||||
break;
|
||||
}
|
||||
else
|
||||
result.push_back (str.substr (start_pos, end_pos - start_pos));
|
||||
|
||||
++start_pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 ProcessSpawner::execute(const std::string & processName, const std::vector<std::string> & parameters)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
char cmd[1024] = {"\0"};
|
||||
std::string cmdLine;
|
||||
|
||||
cmdLine = processName.c_str();
|
||||
cmdLine += " ";
|
||||
std::vector<std::string>::const_iterator i;
|
||||
for(i = parameters.begin(); i != parameters.end(); ++i)
|
||||
{
|
||||
cmdLine += (*i).c_str();
|
||||
cmdLine += " ";
|
||||
}
|
||||
|
||||
_snprintf(cmd, 1024, "%s.exe", processName.c_str());
|
||||
// _snprintf(cmd, 1024, "%s", processName.c_str());
|
||||
memset(&si, 0, sizeof(si));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
|
||||
si.cb = sizeof(si);
|
||||
|
||||
const int result = CreateProcess(cmd, const_cast<char *>(cmdLine.c_str()), NULL, NULL, false, 0, 0, 0, &si, &pi);
|
||||
UNREF (result);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!result)
|
||||
{
|
||||
DWORD iErr = GetLastError();
|
||||
char * errStr = strerror(iErr);
|
||||
DEBUG_REPORT_LOG(true, ("ProcessSpawner: %s - %s\n", cmd, errStr));
|
||||
}
|
||||
#endif
|
||||
|
||||
procById.insert(std::pair<uint32, HANDLE>(pi.dwProcessId, pi.hProcess));
|
||||
return pi.dwProcessId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
uint32 ProcessSpawner::execute(const std::string & cmd)
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
size_t firstArg = cmd.find_first_of(" ");
|
||||
std::string processName;
|
||||
if(firstArg < cmd.size())
|
||||
{
|
||||
std::string a = cmd.substr(firstArg + 1);
|
||||
tokenize(a, args);
|
||||
processName = cmd.substr(0, firstArg);
|
||||
}
|
||||
else
|
||||
{
|
||||
processName = cmd;
|
||||
}
|
||||
return execute(processName, args);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool ProcessSpawner::isProcessActive(uint32 pid)
|
||||
{
|
||||
bool result = false;
|
||||
std::map<uint32, HANDLE>::const_iterator f = procById.find(pid);
|
||||
if(f != procById.end())
|
||||
{
|
||||
DWORD exitCode;
|
||||
GetExitCodeProcess((*f).second, &exitCode);
|
||||
result = (exitCode == STILL_ACTIVE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ProcessSpawner::kill(uint32 pid)
|
||||
{
|
||||
HANDLE p = OpenProcess(PROCESS_TERMINATE, false, (DWORD)pid);
|
||||
if(p)
|
||||
TerminateProcess(p, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ProcessSpawner::forceCore(const unsigned long pid)
|
||||
{
|
||||
ProcessSpawner::kill(pid);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
// TaskManagerSysInfo.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTaskManager.h"
|
||||
#include "TaskManagerSysInfo.h"
|
||||
#pragma warning ( disable : 4201)
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo::TaskManagerSysInfo() :
|
||||
averageScore()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo::TaskManagerSysInfo(const TaskManagerSysInfo &)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo::~TaskManagerSysInfo()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TaskManagerSysInfo & TaskManagerSysInfo::operator = (const TaskManagerSysInfo & rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
{
|
||||
// make assignments if right hand side is not this instance
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const float TaskManagerSysInfo::getScore() const
|
||||
{
|
||||
std::list<float>::const_iterator i;
|
||||
float avg = 0.0f;
|
||||
for(i = averageScore.begin(); i != averageScore.end(); ++i)
|
||||
{
|
||||
avg += (*i);
|
||||
}
|
||||
avg = avg / averageScore.size();
|
||||
return avg;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TaskManagerSysInfo::update()
|
||||
{
|
||||
static int64 activeTime[2] = {0};
|
||||
static int64 currentTime[2] = {0};
|
||||
|
||||
float currentScore = 0.0f;
|
||||
activeTime[0] = activeTime[1];
|
||||
currentTime[0] = currentTime[1];
|
||||
activeTime[1] = 0;
|
||||
|
||||
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
|
||||
double procAvg = 0.0f;
|
||||
|
||||
MEMORYSTATUS memStat;
|
||||
GlobalMemoryStatus(&memStat);
|
||||
|
||||
currentScore = static_cast<float>(static_cast<float>(memStat.dwMemoryLoad) * 0.005f);
|
||||
if(hProcessSnap != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
PROCESSENTRY32 pe32 = {0};
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
if (Process32First(hProcessSnap, &pe32))
|
||||
{
|
||||
do
|
||||
{
|
||||
HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION, false, pe32.th32ProcessID);
|
||||
// some stuf with the enumerated processes
|
||||
FILETIME createTime = {0};
|
||||
FILETIME exitTime = {0};
|
||||
FILETIME kernelTime = {0};
|
||||
FILETIME userTime = {0};
|
||||
GetProcessTimes(proc, &createTime, &exitTime, &kernelTime, &userTime);
|
||||
int64 totals;
|
||||
|
||||
// SDK docs say:
|
||||
// It is not recommended that you add and subtract values
|
||||
// from the FILETIME structure to obtain relative times. Instead, you should
|
||||
// Copy the resulting FILETIME structure to a ULARGE_INTEGER structure.
|
||||
// Use normal 64-bit arithmetic on the ULARGE_INTEGER value.
|
||||
int64 c;
|
||||
int64 e;
|
||||
int64 k;
|
||||
int64 u;
|
||||
memcpy(&c, &createTime, sizeof(int64));
|
||||
memcpy(&e, &exitTime, sizeof(int64));
|
||||
memcpy(&k, &kernelTime, sizeof(int64));
|
||||
memcpy(&u, &userTime, sizeof(int64));
|
||||
|
||||
totals = k + u;
|
||||
|
||||
FILETIME fst;
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &fst);
|
||||
|
||||
int64 runTime;
|
||||
memcpy(&runTime, &fst, sizeof(int64));
|
||||
runTime = runTime - c;
|
||||
|
||||
if(c || e || k || u)
|
||||
{
|
||||
activeTime[1] += k + e;
|
||||
}
|
||||
|
||||
}
|
||||
while (Process32Next(hProcessSnap, &pe32));
|
||||
}
|
||||
}
|
||||
|
||||
FILETIME fst;
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &fst);
|
||||
memcpy(¤tTime[1], &fst, sizeof(int64));
|
||||
int64 timeSlice = currentTime[1] - currentTime[0];
|
||||
int64 activeSlice = activeTime[1] - activeTime[0];
|
||||
procAvg = static_cast<double>(static_cast<double>(activeSlice) / timeSlice);
|
||||
//REPORT_LOG(true, ("%f\n", procAvg));
|
||||
currentScore = currentScore + static_cast<float>(procAvg * 0.5);
|
||||
|
||||
averageScore.insert(averageScore.end(), currentScore);
|
||||
|
||||
if(averageScore.size() > 100)
|
||||
averageScore.erase(averageScore.begin());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "FirstTaskManager.h"
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedCompression/SetupSharedCompression.h"
|
||||
#include "sharedDebug/SetupSharedDebug.h"
|
||||
#include "sharedFile/SetupSharedFile.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
|
||||
#include "sharedThread/SetupSharedThread.h"
|
||||
#include "TaskManager.h"
|
||||
#include "ConfigTaskManager.h"
|
||||
|
||||
//=====================================================================
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SetupSharedThread::install();
|
||||
SetupSharedDebug::install(1024);
|
||||
|
||||
//-- setup foundation
|
||||
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
|
||||
|
||||
setupFoundationData.argc = argc;
|
||||
setupFoundationData.argv = argv;
|
||||
setupFoundationData.createWindow = false;
|
||||
setupFoundationData.clockUsesSleep = true;
|
||||
SetupSharedFoundation::install (setupFoundationData);
|
||||
|
||||
SetupSharedCompression::install();
|
||||
SetupSharedNetworkMessages::install();
|
||||
ConfigTaskManager::install();
|
||||
|
||||
//-- run server
|
||||
SetupSharedFoundation::callbackWithExceptionHandling(TaskManager::run);
|
||||
|
||||
SetupSharedFoundation::remove();
|
||||
SetupSharedThread::remove();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
Reference in New Issue
Block a user