Blob Blame Raw


#include "tconvert.h"
#include "tfarmcontroller.h"
#include "ttcpip.h"

#include "texception.h"
#include "tfarmproxy.h"
#include "tfilepath_io.h"

#include <strstream>

namespace
{

//------------------------------------------------------------------------------

class Controller : public TFarmController, public TFarmProxy
{
public:
	Controller(const QString &hostName, const QString &addr, int port)
		: TFarmProxy(hostName, addr, port) {}

	// TFarmController interface implementation

	QString addTask(const TFarmTask &task, bool suspended);

	void removeTask(const QString &id);
	void suspendTask(const QString &id);
	void activateTask(const QString &id);
	void restartTask(const QString &id);

	void getTasks(vector<QString> &tasks);
	void getTasks(const QString &parentId, vector<QString> &tasks);
	void getTasks(const QString &parentId, vector<TaskShortInfo> &tasks);

	void queryTaskInfo(const QString &id, TFarmTask &task);

	void queryTaskShortInfo(
		const QString &id,
		QString &parentId,
		QString &name,
		TaskState &status);

	void attachServer(const QString &name, const QString &addr, int port);

	void detachServer(const QString &name, const QString &addr, int port);

	void taskSubmissionError(const QString &taskId, int errCode);

	void taskProgress(
		const QString &taskId,
		int step,
		int stepCount,
		int frameNumber,
		FrameState state);

	void taskCompleted(const QString &taskId, int exitCode);

	// fills the servers vector with the names of the servers
	void getServers(vector<ServerIdentity> &servers);

	// returns the state of the server whose id has been specified
	ServerState queryServerState2(const QString &id);

	// fills info with the infoes about the server whose id has been specified
	void queryServerInfo(const QString &id, ServerInfo &info);

	// activates the server whose id has been specified
	void activateServer(const QString &id);

	// deactivates the server whose id has been specified
	// once deactivated, a server is not available for task rendering
	void deactivateServer(const QString &id, bool completeRunningTasks = true);
};

//------------------------------------------------------------------------------

QString Controller::addTask(const TFarmTask &task, bool suspended)
{
	int i, count = task.getTaskCount();

	QString data("addTask@TFarmTask_2");
	data += ",";
	data += task.m_name;
	data += ",";
	data += task.getCommandLine(true);
	data += ",";
	data += task.m_user;
	data += ",";
	data += task.m_hostName;
	data += ",";
	data += QString::number(suspended);
	data += ",";
	data += QString::number(task.m_stepCount);
	data += ",";
	data += QString::number(task.m_priority);
	data += ",";
	data += QString::number(task.m_platform);

	data += ",";
	int depCount = task.m_dependencies->getTaskCount();
	data += QString::number(depCount);

	i = 0;
	for (; i < depCount; ++i) {
		data += ",";
		data += task.m_dependencies->getTaskId(i);
	}

	for (i = 0; i < count; ++i) {
		TFarmTask &tt = const_cast<TFarmTask &>(task);
		TFarmTask *subtask = tt.getTask(i);

		data += ",";
		data += subtask->m_name;
		data += ",";
		data += subtask->getCommandLine(true);
		data += ",";
		data += subtask->m_user;
		data += ",";
		data += subtask->m_hostName;
		data += ",";
		data += QString::number(subtask->m_stepCount);
		data += ",";
		data += QString::number(subtask->m_priority);
	}

	QString reply = sendToStub(data);
	//MessageBox(NULL, data.c_str(), "ciao", 0);
	return reply;
}

//------------------------------------------------------------------------------

void Controller::removeTask(const QString &id)
{
	QString data("removeTask");
	data += ",";
	data += id;

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::suspendTask(const QString &id)
{
	QString data("suspendTask");
	data += ",";
	data += id;

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::activateTask(const QString &id)
{
	QString data("activateTask");
	data += ",";
	data += id;

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::restartTask(const QString &id)
{
	QString data("restartTask");
	data += ",";
	data += id;

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::getTasks(vector<QString> &tasks)
{
	QString data("getTasks@vector");
	QString reply = sendToStub(data);

	// la stringa restituita contiene le informazioni desiderate separate da ","
	vector<QString> argv;
	extractArgs(reply, argv);

	tasks.clear();
	std::vector<QString>::iterator it = argv.begin();
	for (; it != argv.end(); ++it)
		tasks.push_back(*it);
}

//------------------------------------------------------------------------------

void Controller::getTasks(const QString &parentId, vector<QString> &tasks)
{
	QString data("getTasks@string@vector");
	data += ",";
	data += parentId;

	QString reply = sendToStub(data);

	// la stringa restituita contiene le informazioni deiderate separate da ","
	vector<QString> argv;
	extractArgs(reply, argv);

	tasks.clear();
	std::vector<QString>::iterator it = argv.begin();
	for (; it != argv.end(); ++it)
		tasks.push_back(*it);
}

//------------------------------------------------------------------------------

void Controller::getTasks(const QString &parentId, vector<TaskShortInfo> &tasks)
{
	QString data("getTasks@string@vector$TaskShortInfo");
	data += ",";
	data += parentId;

	QString reply = sendToStub(data);

	// la stringa restituita contiene le informazioni desiderate separate da ","
	vector<QString> argv;
	extractArgs(reply, argv);

	tasks.clear();
	std::vector<QString>::iterator it = argv.begin();
	for (; it != argv.end(); ++it) {
		QString id = *it++;
		QString name = *it++;
		TaskState status;
		status = (TaskState)(*it).toInt();

		tasks.push_back(TaskShortInfo(id, name, status));
	}
}

//------------------------------------------------------------------------------

void Controller::queryTaskInfo(const QString &id, TFarmTask &task)
{
	QString data("queryTaskInfo_2");
	data += ",";
	data += id;

	QString reply = sendToStub(data);

	// la stringa restituita contiene le informazioni desiderate separate da ","
	vector<QString> argv;
	int count = extractArgs(reply, argv);

	if (reply == "")
		return;

	assert(argv.size() > 15);
	int incr = 0;
	task.m_name = argv[incr++];
	task.parseCommandLine(argv[incr++]);
	task.m_priority = argv[incr++].toInt();

	task.m_user = argv[incr++];
	task.m_hostName = argv[incr++];

	task.m_id = argv[incr++];
	task.m_parentId = argv[incr++];

	task.m_status = (TaskState)argv[incr++].toInt();

	task.m_server = argv[incr++];
	task.m_submissionDate = QDateTime::fromString(argv[incr++]);
	task.m_startDate = QDateTime::fromString(argv[incr++]);
	task.m_completionDate = QDateTime::fromString(argv[incr++]);

	task.m_successfullSteps = argv[incr++].toInt();
	task.m_failedSteps = argv[incr++].toInt();
	task.m_stepCount = argv[incr++].toInt();

	if (incr < count) {
		task.m_platform = (TFarmPlatform)argv[incr++].toInt();
		int depCount = 0;
		depCount = argv[incr++].toInt();
		if (depCount > 0) {
			task.m_dependencies = new TFarmTask::Dependencies;
			for (int i = 0; i < depCount; ++i)
				task.m_dependencies->add(argv[incr++]);
		}
	}
}

//------------------------------------------------------------------------------

void Controller::queryTaskShortInfo(
	const QString &id, QString &parentId,
	QString &name, TaskState &status)
{
	QString data("queryTaskShortInfo");
	data += ",";
	data += id;

	QString reply = sendToStub(data);

	// la stringa restituita contiene le informazioni desiderate separate da ","
	vector<QString> argv;
	extractArgs(reply, argv);

	assert(argv.size() == 3);

	parentId = argv[0];
	name = argv[1];
	status = (TaskState)argv[2].toInt();
}

//------------------------------------------------------------------------------

void Controller::attachServer(const QString &name, const QString &addr, int port)
{
	QString data("attachServer");
	data += ",";
	data += name;
	data += ",";
	data += addr;
	data += ",";
	data += QString::number(port);

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::detachServer(const QString &name, const QString &addr, int port)
{
	QString data("detachServer");
	data += ",";
	data += name;
	data += ",";
	data += addr;
	data += ",";
	data += QString::number(port);

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::taskSubmissionError(const QString &taskId, int errCode)
{
	QString data("taskSubmissionError");
	data += ",";
	data += taskId;
	data += ",";
	data += QString::number(errCode);

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::taskProgress(
	const QString &taskId,
	int step,
	int stepCount,
	int frameNumber,
	FrameState state)
{
	QString data("taskProgress");
	data += ",";
	data += taskId;
	data += ",";
	data += QString::number(step);
	data += ",";
	data += QString::number(stepCount);
	data += ",";
	data += QString::number(frameNumber);
	data += ",";
	data += QString::number(state);

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::taskCompleted(const QString &taskId, int exitCode)
{
	QString data("taskCompleted");
	data += ",";
	data += taskId;
	data += ",";
	data += QString::number(exitCode);

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::getServers(vector<ServerIdentity> &servers)
{
	QString data("getServers");
	QString reply = sendToStub(data);

	// la stringa restituita contiene le informazioni desiderate separate da ","
	vector<QString> argv;
	extractArgs(reply, argv);

	servers.clear();
	std::vector<QString>::iterator it = argv.begin();
	for (; it != argv.end(); it += 2)
		servers.push_back(ServerIdentity(*it, *(it + 1)));
}

//------------------------------------------------------------------------------

ServerState Controller::queryServerState2(const QString &name)
{
	QString data("queryServerState2");
	data += ",";
	data += name;

	QString reply = sendToStub(data);

	ServerState serverState = (ServerState)reply.toInt();
	return serverState;
}

//------------------------------------------------------------------------------

void Controller::queryServerInfo(const QString &id, ServerInfo &info)
{
	QString data("queryServerInfo");
	data += ",";
	data += id;

	QString reply = sendToStub(data);
	if (reply != "") {
		// la stringa restituita contiene le informazioni desiderate separate da ","
		vector<QString> argv;
		extractArgs(reply, argv);

		info.m_name = argv[0];
		info.m_ipAddress = argv[1];
		info.m_portNumber = argv[2];
		info.m_state = (ServerState)argv[3].toInt();
		info.m_platform = argv[4];

		int cpuCount, totPhysMem, totVirtMem, availPhysMem, availVirtMem;

		cpuCount = argv[5].toInt();
		totPhysMem = argv[6].toInt();
		totVirtMem = argv[7].toInt();
		availPhysMem = argv[8].toInt();
		availVirtMem = argv[9].toInt();
		info.m_currentTaskId = argv[10];

		info.m_cpuCount = cpuCount;
		info.m_totPhysMem = totPhysMem;
		info.m_totVirtMem = totVirtMem;
		info.m_availPhysMem = availPhysMem;
		info.m_availVirtMem = availVirtMem;
	}
}

//------------------------------------------------------------------------------

void Controller::activateServer(const QString &id)
{
	QString data("activateServer");
	data += ",";
	data += id;

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

void Controller::deactivateServer(const QString &id, bool completeRunningTasks)
{
	QString data("deactivateServer");
	data += ",";
	data += id;
	data += ",";
	data += QString::number(completeRunningTasks);

	QString reply = sendToStub(data);
}

//------------------------------------------------------------------------------

} // anonymous namespace

//==============================================================================

TFarmControllerFactory::TFarmControllerFactory()
{
}

//------------------------------------------------------------------------------

int TFarmControllerFactory::create(const ControllerData &data,
								   TFarmController **controller)

{
	*controller = new Controller(data.m_hostName, data.m_ipAddress, data.m_port);
	return 0;
}

//------------------------------------------------------------------------------

int TFarmControllerFactory::create(const QString &hostname, int port, TFarmController **controller)
{
	*controller = new Controller(hostname, "", port);
	return 0;
}

//------------------------------------------------------------------------------

void loadControllerData(const TFilePath &fp, ControllerData &data)
{
	Tifstream is(fp);
	if (!is || !is.good()) {
		throw TException(
			L"Unable to get Farm Controller Data (looking for '" + fp.getWideString() + L"')");
	}

	while (!is.eof()) {
		char line[1024];
		is.getline(line, 1024);

		if (line[0] != '#' && QString(line) != "") {
			std::istrstream iss(line);

			char hostName[512];
			char ipAddr[80];
			int port;

			iss >> hostName >> ipAddr >> port;

			data.m_hostName = hostName;
			data.m_ipAddress = ipAddr;
			data.m_port = port;
			break;
		}
	}
}