Added: Content database status update command.

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 13 years ago
parent 5dfa3ea35a
commit 3fe8c02aa5

@ -36,6 +36,7 @@
#include <nel/misc/path.h> #include <nel/misc/path.h>
// Project includes // Project includes
#include "pipeline_service.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -71,14 +72,24 @@ CDatabaseStatus::~CDatabaseStatus()
bool CDatabaseStatus::getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const bool CDatabaseStatus::getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const
{ {
// mutex here when reading
return false; return false;
} }
void CDatabaseStatus::updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath) void CDatabaseStatus::updateFileStatus(TFileStatusCallback &callback, const std::string &filePath)
{ {
// ONLY WHEN MASTER
// mutex when writing
// dummy
CFileStatus fs;
callback(filePath, fs);
// todo add to queue
} }
// ******************************************************************
namespace {
struct CDatabaseStatusUpdater struct CDatabaseStatusUpdater
{ {
public: public:
@ -106,6 +117,38 @@ public:
} }
}; };
void updateDirectoryStatus(CDatabaseStatus* ds, CDatabaseStatusUpdater &updater, const std::string &dir)
{
std::string dirPath = CPath::standardizePath(dir, true);
std::vector<std::string> dirContents;
CPath::getPathContent(dirPath, false, true, true, dirContents);
for (std::vector<std::string>::iterator it = dirContents.begin(), end = dirContents.end(); it != end; ++it)
{
const std::string subPath = *it;
if (CFile::isDirectory(subPath)) // if the file is a directory!
{
updateDirectoryStatus(ds, updater, subPath);
}
else
{
updater.Mutex.enter();
++updater.FilesRequested;
updater.Mutex.leave();
CFileStatus fileStatus;
if (!ds->getFileStatus(fileStatus, subPath))
{
ds->updateFileStatus(TFileStatusCallback(&updater, &CDatabaseStatusUpdater::fileUpdated), subPath);
}
}
}
}
} /* anonymous namespace */
void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback) void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
{ {
CDatabaseStatusUpdater updater; CDatabaseStatusUpdater updater;
@ -115,14 +158,13 @@ void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
updater.Ready = false; updater.Ready = false;
updater.CallbackCalled = false; updater.CallbackCalled = false;
// recursive loop ... nlinfo("Starting iteration through database, queueing file status updates.");
{
updater.Mutex.enter(); // recursive loop
++updater.FilesRequested; updateDirectoryStatus(this, updater, g_DatabaseDirectory);
updater.Mutex.leave();
updateFileStatus(TFileStatusCallback(&updater, &CDatabaseStatusUpdater::fileUpdated), ""); nlinfo("Iteration through database, queueing file status updates complete.");
}
bool done = false; bool done = false;
updater.Mutex.enter(); updater.Mutex.enter();
updater.Ready = true; updater.Ready = true;
@ -136,6 +178,8 @@ void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
if (done) updater.Callback(); if (done) updater.Callback();
} }
// ******************************************************************
} /* namespace PIPELINE */ } /* namespace PIPELINE */
/* end of file */ /* end of file */

@ -90,7 +90,7 @@ public:
/// Tries to read the last file status. Return false if the status is invalid. Call updateFileStatus if the result is false to update asynchronously. /// Tries to read the last file status. Return false if the status is invalid. Call updateFileStatus if the result is false to update asynchronously.
bool getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const; bool getFileStatus(CFileStatus &fileStatus, const std::string &filePath) const;
/// Updates the file status asynchronously. The new file status is broadcast to clients and slaves afterwards. /// Updates the file status asynchronously. The new file status is broadcast to clients and slaves afterwards.
void updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath); void updateFileStatus(TFileStatusCallback &callback, const std::string &filePath);
/// Forces an update of the complete database status. /// Forces an update of the complete database status.
void updateDatabaseStatus(const CCallback<void> &callback); void updateDatabaseStatus(const CCallback<void> &callback);

@ -46,6 +46,7 @@
// Project includes // Project includes
#include "pipeline_workspace.h" #include "pipeline_workspace.h"
#include "database_status.h"
// using namespace std; // using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -75,6 +76,7 @@ enum EState
UFormLoader *s_FormLoader = NULL; UFormLoader *s_FormLoader = NULL;
CPipelineWorkspace *s_PipelineWorkspace = NULL; CPipelineWorkspace *s_PipelineWorkspace = NULL;
CTaskManager *s_TaskManager = NULL; CTaskManager *s_TaskManager = NULL;
CDatabaseStatus *s_DatabaseStatus = NULL;
EState s_State = STATE_IDLE; EState s_State = STATE_IDLE;
CMutex s_StateMutex; CMutex s_StateMutex;
@ -93,21 +95,35 @@ TUnifiedCallbackItem s_ShardCallbacks[] = // pipeline_server
{ "N", cbNull }, { "N", cbNull },
}; };
bool tryStateTask(EState state, IRunnable *task)
{
bool result = false;
s_StateMutex.enter();
result = (s_State == STATE_IDLE);
if (result)
{
s_State = state;
}
s_StateMutex.leave();
if (!result) return false;
s_TaskManager->addTask(task);
return true;
}
// ****************************************************************** // ******************************************************************
void initSheets() void initSheets()
{ {
std::string leveldesignDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDirectory").asString();
std::string leveldesignDfnDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDfnDirectory").asString(); std::string leveldesignDfnDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignDfnDirectory").asString();
std::string leveldesignPipelineDirectory = IService::getInstance()->ConfigFile.getVar("LeveldesignPipelineDirectory").asString();
if (leveldesignDfnDirectory.find(leveldesignDirectory) == std::string::npos)
{ nlinfo("Adding 'LeveldesignDfnDirectory' to search path (%s)", leveldesignDfnDirectory.c_str());
nlinfo("Adding 'LeveldesignDfnDirectory' to search path"); CPath::addSearchPath(leveldesignDfnDirectory, true, false);
CPath::addSearchPath(leveldesignDfnDirectory, true, false);
} nlinfo("Adding 'LeveldesignPipelineDirectory' to search path (%s)", leveldesignPipelineDirectory.c_str());
CPath::addSearchPath(leveldesignPipelineDirectory, true, false);
nlinfo("Adding 'LeveldesignDirectory' to search path");
CPath::addSearchPath(leveldesignDirectory, true, false);
s_FormLoader = UFormLoader::createLoader(); s_FormLoader = UFormLoader::createLoader();
@ -144,19 +160,33 @@ CReloadSheets s_ReloadSheets;
bool reloadSheets() bool reloadSheets()
{ {
bool result = false; return tryStateTask(STATE_RELOAD_SHEETS, &s_ReloadSheets);
s_StateMutex.enter(); }
result = (s_State == STATE_IDLE);
if (result) // ******************************************************************
class CUpdateDatabaseStatus : public IRunnable
{
virtual void getName (std::string &result) const
{ result = "CUpdateDatabaseStatus"; }
void databaseStatusUpdated()
{ {
s_State = STATE_RELOAD_SHEETS; s_StateMutex.enter();
s_State = STATE_IDLE;
s_StateMutex.leave();
} }
s_StateMutex.leave();
if (!result) return false; virtual void run()
{
s_TaskManager->addTask(&s_ReloadSheets); s_DatabaseStatus->updateDatabaseStatus(CCallback<void>(this, &CUpdateDatabaseStatus::databaseStatusUpdated));
}
return true; };
CUpdateDatabaseStatus s_UpdateDatabaseStatus;
bool updateDatabaseStatus()
{
return tryStateTask(STATE_DATABASE_STATUS, &s_UpdateDatabaseStatus);
} }
// ****************************************************************** // ******************************************************************
@ -206,6 +236,8 @@ public:
s_TaskManager = new CTaskManager(); s_TaskManager = new CTaskManager();
initSheets(); initSheets();
s_DatabaseStatus = new CDatabaseStatus();
} }
/// This function is called every "frame" (you must call init() before). It returns false if the service is stopped. /// This function is called every "frame" (you must call init() before). It returns false if the service is stopped.
@ -217,9 +249,13 @@ public:
/// Finalization. Release the service. For example, this function frees all allocations made in the init() function. /// Finalization. Release the service. For example, this function frees all allocations made in the init() function.
virtual void release() virtual void release()
{ {
delete s_DatabaseStatus;
s_DatabaseStatus = NULL;
releaseSheets(); releaseSheets();
delete s_TaskManager; delete s_TaskManager;
s_TaskManager = NULL;
} }
}; /* class CPipelineService */ }; /* class CPipelineService */
@ -252,15 +288,22 @@ NLMISC_COMMAND(reloadSheets, "Reload all sheets.", "")
{ {
if(args.size() != 0) return false; if(args.size() != 0) return false;
if (!PIPELINE::reloadSheets()) if (!PIPELINE::reloadSheets())
{
nlinfo("I'm afraid I cannot do this, my friend."); nlinfo("I'm afraid I cannot do this, my friend.");
return false;
}
return true; return true;
} }
NLMISC_COMMAND(updateDatabaseStatus, "Updates the entire database status. This also happens on the fly during build.", "") NLMISC_COMMAND(updateDatabaseStatus, "Updates the entire database status. This also happens on the fly during build.", "")
{ {
if(args.size() != 0) return false; if(args.size() != 0) return false;
if (!PIPELINE::updateDatabaseStatus())
{
nlinfo("I'm afraid I cannot do this, my friend.");
return false;
}
return true;
} }
NLNET_SERVICE_MAIN(PIPELINE::CPipelineService, PIPELINE_SHORT_SERVICE_NAME, PIPELINE_LONG_SERVICE_NAME, 0, PIPELINE::s_ShardCallbacks, "", "") NLNET_SERVICE_MAIN(PIPELINE::CPipelineService, PIPELINE_SHORT_SERVICE_NAME, PIPELINE_LONG_SERVICE_NAME, 0, PIPELINE::s_ShardCallbacks, "", "")

@ -13,5 +13,7 @@
<LOG>Sat Feb 18 13:48:48 2012 (Kaetemi) .Name = Ryzom Core <LOG>Sat Feb 18 13:48:48 2012 (Kaetemi) .Name = Ryzom Core
Sat Feb 18 13:48:48 2012 (Kaetemi) formName Resized = 1 Sat Feb 18 13:48:48 2012 (Kaetemi) formName Resized = 1
Sat Feb 18 14:44:25 2012 (Kaetemi) .Description = Ryzom Core Sat Feb 18 14:44:25 2012 (Kaetemi) .Description = Ryzom Core
Sat Feb 18 14:44:37 2012 (Kaetemi) .Projects[0] = common_interface.pipeline_project</LOG> Sat Feb 18 14:44:37 2012 (Kaetemi) .Projects[0] = common_interface.pipeline_project
Sat Feb 18 23:23:17 2012 (Kaetemi) .Description = Ryzom Core Test
Sat Feb 18 23:23:26 2012 (Kaetemi) .Description = Ryzom Core</LOG>
</FORM> </FORM>

Loading…
Cancel
Save