diff --git a/code/nel/tools/pipeline/pipeline_service/database_status.cpp b/code/nel/tools/pipeline/pipeline_service/database_status.cpp index a4b66bf98..30f618555 100644 --- a/code/nel/tools/pipeline/pipeline_service/database_status.cpp +++ b/code/nel/tools/pipeline/pipeline_service/database_status.cpp @@ -29,11 +29,13 @@ #include "database_status.h" // STL includes +#include // NeL includes // #include #include #include +#include // Project includes #include "pipeline_service.h" @@ -43,6 +45,23 @@ using namespace NLMISC; namespace PIPELINE { +namespace { + +std::string dropDatabaseDirectory(const std::string &path) +{ + if (path.find(g_DatabaseDirectory) == 0) + { + return path.substr(g_DatabaseDirectory.length()); + } + else + { + nlerror("Path is not in database."); + return path; + } +} + +} /* anonymous namespace */ + void CFileError::serial(NLMISC::IStream &stream) { uint version = stream.serialVersion(1); @@ -62,7 +81,8 @@ void CFileStatus::serial(NLMISC::IStream &stream) CDatabaseStatus::CDatabaseStatus() { - + CFile::createDirectoryTree(g_PipelineDirectory + PIPELINE_DATABASE_STATUS_SUBDIR); + CFile::createDirectoryTree(g_PipelineDirectory + PIPELINE_DATABASE_ERRORS_SUBDIR); } CDatabaseStatus::~CDatabaseStatus() @@ -76,14 +96,83 @@ bool CDatabaseStatus::getFileStatus(CFileStatus &fileStatus, const std::string & return false; } -void CDatabaseStatus::updateFileStatus(TFileStatusCallback &callback, const std::string &filePath) +namespace { + +class CUpdateFileStatus : public IRunnable +{ +public: + virtual void getName(std::string &result) const + { result = "CUpdateFileStatus"; } + + TFileStatusCallback Callback; + std::string FilePath; + CMutex *StatusMutex; + + virtual void run() + { + nldebug("Run this"); + bool firstSeen = false; + uint32 time = CTime::getSecondsSince1970(); + std::string statusPath = g_PipelineDirectory + PIPELINE_DATABASE_STATUS_SUBDIR + dropDatabaseDirectory(FilePath) + ".status"; + CFileStatus fs; + StatusMutex->enter(); + if (CFile::fileExists(statusPath)) + { + CIFile ifs(statusPath, false); + fs.serial(ifs); + ifs.close(); + } + else + { + firstSeen = true; + } + StatusMutex->leave(); + if (firstSeen) + { + fs.FirstSeen = time; + fs.CRC32 = 0; + nldebug("First seen file: '%s'", FilePath.c_str()); + + // create dir + CFile::createDirectoryTree(g_PipelineDirectory + PIPELINE_DATABASE_STATUS_SUBDIR + dropDatabaseDirectory(CFile::getPath(FilePath))); + } + fs.LastChanged = CFile::getFileModificationDate(FilePath); + fs.LastUpdate = time; + + nldebug("Calculate crc32 of file: '%s'", FilePath.c_str()); + nlSleep(1000); + // calculate crc32 etcetera etcetera + + StatusMutex->enter(); + { + COFile ofs(statusPath, false, false, true); + fs.serial(ofs); + ofs.flush(); + ofs.close(); + } + StatusMutex->leave(); + nldebug("Callback"); + Callback(FilePath, fs); + nldebug("Delete this"); + delete this; + } +}; + +} /* anonymous namespace */ + +void CDatabaseStatus::updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath) { - // ONLY WHEN MASTER - // mutex when writing - // dummy - CFileStatus fs; - callback(filePath, fs); - // todo add to queue + if (!g_IsMaster) + { + nlerror("Not master, not allowed."); + return; + } + + CUpdateFileStatus *ufs = new CUpdateFileStatus(); + ufs->StatusMutex = &m_StatusMutex; + ufs->FilePath = filePath; + ufs->Callback = callback; + CAsyncFileManager::getInstance().addLoadTask(ufs); } // ****************************************************************** @@ -103,6 +192,8 @@ public: void fileUpdated(const std::string &filePath, const CFileStatus &fileStatus) { + nldebug("File updated callback"); + bool done = false; Mutex.enter(); ++FilesUpdated; diff --git a/code/nel/tools/pipeline/pipeline_service/database_status.h b/code/nel/tools/pipeline/pipeline_service/database_status.h index 80b171420..ca63f26ba 100644 --- a/code/nel/tools/pipeline/pipeline_service/database_status.h +++ b/code/nel/tools/pipeline/pipeline_service/database_status.h @@ -41,8 +41,8 @@ namespace PIPELINE { -#define PIPELINE_DATABASE_STATUS_SUBDIR "database.status" -#define PIPELINE_DATABASE_ERRORS_SUBDIR "database.errors" +#define PIPELINE_DATABASE_STATUS_SUBDIR "database.status/" +#define PIPELINE_DATABASE_ERRORS_SUBDIR "database.errors/" struct CFileError { @@ -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. 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. - void updateFileStatus(TFileStatusCallback &callback, const std::string &filePath); + void updateFileStatus(const TFileStatusCallback &callback, const std::string &filePath); /// Forces an update of the complete database status. void updateDatabaseStatus(const CCallback &callback); diff --git a/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp b/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp index fdb77409d..552c36b3d 100644 --- a/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp +++ b/code/nel/tools/pipeline/pipeline_service/pipeline_service.cpp @@ -143,7 +143,7 @@ void releaseSheets() class CReloadSheets : public IRunnable { - virtual void getName (std::string &result) const + virtual void getName(std::string &result) const { result = "CReloadSheets"; } virtual void run() @@ -167,7 +167,7 @@ bool reloadSheets() class CUpdateDatabaseStatus : public IRunnable { - virtual void getName (std::string &result) const + virtual void getName(std::string &result) const { result = "CUpdateDatabaseStatus"; } void databaseStatusUpdated() @@ -230,8 +230,10 @@ public: virtual void init() { g_IsMaster = ConfigFile.getVar("IsMaster").asBool(); - g_DatabaseDirectory = ConfigFile.getVar("DatabaseDirectory").asString(); - g_PipelineDirectory = ConfigFile.getVar("PipelineDirectory").asString(); + g_DatabaseDirectory = CPath::standardizePath(ConfigFile.getVar("DatabaseDirectory").asString(), true); + if (!CFile::isDirectory(g_DatabaseDirectory)) nlwarning("'DatabaseDirectory' does not exist! (%s)", g_DatabaseDirectory.c_str()); + g_PipelineDirectory = CPath::standardizePath(ConfigFile.getVar("PipelineDirectory").asString(), true); + if (!CFile::isDirectory(g_PipelineDirectory)) nlwarning("'PipelineDirectory' does not exist! (%s)", g_PipelineDirectory.c_str()); s_TaskManager = new CTaskManager();