Added: #1440 Send requested status updates from the master to the slave cache

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 12 years ago
parent b4619055d6
commit be30ccea4d

@ -324,9 +324,13 @@ public:
std::vector<IRunnable *> RequestTasks; std::vector<IRunnable *> RequestTasks;
TFileStatusCallback FileStatusCallback;
void fileUpdated(const std::string &filePath, const CFileStatus &fileStatus, bool success) void fileUpdated(const std::string &filePath, const CFileStatus &fileStatus, bool success)
{ {
// warning: may be g_IsExiting during this callback! // warning: may be g_IsExiting during this callback!
if (!g_IsExiting)
FileStatusCallback(filePath, fileStatus, success);
bool done = false; bool done = false;
Mutex.enter(); Mutex.enter();
@ -409,6 +413,12 @@ void updatePathStatus(CDatabaseStatus* ds, CDatabaseStatusUpdater &updater, cons
} }
updater.Mutex.leave(); updater.Mutex.leave();
} }
else
{
// File was not updated, but the status was read successfully
// This only notifies the callback set by the user
updater.FileStatusCallback(subPath, fileStatus, true);
}
} }
} }
@ -499,6 +509,8 @@ void updateDirectoryStatus(CDatabaseStatus* ds, CDatabaseStatusUpdater &updater,
} /* anonymous namespace */ } /* anonymous namespace */
void dummyFileStatusCallback(const std::string &/*filePath*/, const CFileStatus &/*fileStatus*/, bool /*success*/) { }
void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback) void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
{ {
/*if (!g_IsMaster) /*if (!g_IsMaster)
@ -516,10 +528,10 @@ void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback)
std::string rootDirectoryPath = standardizePath(dir.asString(), true); std::string rootDirectoryPath = standardizePath(dir.asString(), true);
paths.push_back(rootDirectoryPath); paths.push_back(rootDirectoryPath);
} }
updateDatabaseStatus(callback, paths, false, true); updateDatabaseStatus(callback, dummyFileStatusCallback, paths, false, true);
} }
void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback, const std::vector<std::string> &paths, bool wait, bool recurse) void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback, const TFileStatusCallback &fileStatusCallback, const std::vector<std::string> &paths, bool wait, bool recurse)
{ {
/*if (!g_IsMaster) /*if (!g_IsMaster)
{ {
@ -532,6 +544,7 @@ void CDatabaseStatus::updateDatabaseStatus(const CCallback<void> &callback, cons
updater->FilesUpdated = 0; updater->FilesUpdated = 0;
updater->Ready = false; updater->Ready = false;
updater->CallbackCalled = false; updater->CallbackCalled = false;
updater->FileStatusCallback = fileStatusCallback;
nlinfo("Starting iteration through database, queueing file status updates."); nlinfo("Starting iteration through database, queueing file status updates.");

@ -74,7 +74,7 @@ public:
/// Runs an update of the complete {{DatabaseDirectory}} status asynchronously. Warning: If g_IsExiting during callback then update is incomplete. Callback is always called when done (or failed). /// Runs an update of the complete {{DatabaseDirectory}} status asynchronously. Warning: If g_IsExiting during callback then update is incomplete. Callback is always called when done (or failed).
void updateDatabaseStatus(const CCallback<void> &callback); void updateDatabaseStatus(const CCallback<void> &callback);
/// Runs an update of the file status of given paths asynchronously. Warning: If g_IsExiting during callback then update is incomplete. Callback is always called when done (or failed). Do NOT use the wait parameter. Do NOT use recurse, please. Recurse directories beforehand. Paths may contain db and pl macros. /// Runs an update of the file status of given paths asynchronously. Warning: If g_IsExiting during callback then update is incomplete. Callback is always called when done (or failed). Do NOT use the wait parameter. Do NOT use recurse, please. Recurse directories beforehand. Paths may contain db and pl macros.
void updateDatabaseStatus(const CCallback<void> &callback, const std::vector<std::string> &paths, bool wait = false, bool recurse = false); void updateDatabaseStatus(const CCallback<void> &callback, const TFileStatusCallback &fileStatusCallback, const std::vector<std::string> &paths, bool wait = false, bool recurse = false);
/// Gets the last file statuses of given paths in a map. Directories are scanned for files, non recursively. Returns false if one of the statuses is bad (not updated; file changed inbetween). Considered as build error. /// Gets the last file statuses of given paths in a map. Directories are scanned for files, non recursively. Returns false if one of the statuses is bad (not updated; file changed inbetween). Considered as build error.
bool getFileStatus(std::map<std::string, CFileStatus> &fileStatusMap, std::map<std::string, CFileRemove> &fileRemoveMap, const std::vector<std::string> &paths); bool getFileStatus(std::map<std::string, CFileStatus> &fileStatusMap, std::map<std::string, CFileRemove> &fileRemoveMap, const std::vector<std::string> &paths);

@ -222,12 +222,14 @@ public:
return true; return true;
} }
static void dummyFileStatusCallback(const std::string &/*filePath*/, const CFileStatus &/*fileStatus*/, bool /*success*/) { }
void updateSheetsDatabaseStatus(const CCallback<void> &callback) void updateSheetsDatabaseStatus(const CCallback<void> &callback)
{ {
std::vector<std::string> sheetPaths; std::vector<std::string> sheetPaths;
// sheetPaths.push_back(NLNET::IService::getInstance()->ConfigFile.getVar("WorkspaceDfnDirectory").asString()); // not really necessary to check the dfn's // sheetPaths.push_back(NLNET::IService::getInstance()->ConfigFile.getVar("WorkspaceDfnDirectory").asString()); // not really necessary to check the dfn's
sheetPaths.push_back(NLNET::IService::getInstance()->ConfigFile.getVar("WorkspaceSheetDirectory").asString()); sheetPaths.push_back(NLNET::IService::getInstance()->ConfigFile.getVar("WorkspaceSheetDirectory").asString());
g_DatabaseStatus->updateDatabaseStatus(callback, sheetPaths, false, true); g_DatabaseStatus->updateDatabaseStatus(callback, dummyFileStatusCallback, sheetPaths, false, true);
} }
void cbMasterInitSheets() void cbMasterInitSheets()
@ -320,14 +322,16 @@ public:
void handleUpdateTasks() void handleUpdateTasks()
{ {
uint maxRuns;
IRunnable *currentRunnable; IRunnable *currentRunnable;
{ {
NLMISC::CSynchronized<std::deque<IRunnable *> >::CAccessor updateTasks(&m_UpdateTasks); NLMISC::CSynchronized<std::deque<IRunnable *> >::CAccessor updateTasks(&m_UpdateTasks);
if (updateTasks.value().size() == 0) if (updateTasks.value().size() == 0)
return; return;
maxRuns = updateTasks.value().size();
currentRunnable = updateTasks.value().front(); currentRunnable = updateTasks.value().front();
} }
for (; ; ) for (uint i = 0; i < maxRuns; ++i)
{ {
currentRunnable->run(); currentRunnable->run();
{ {
@ -544,9 +548,48 @@ public:
class CUpdateDatabaseStatusSlaveCallback : public CDelayedCallback class CUpdateDatabaseStatusSlaveCallback : public CDelayedCallback
{ {
class CSlaveFileCallback : public NLMISC::IRunnable
{
public:
CSlaveFileCallback(CModulePipelineMaster *master, NLNET::IModuleProxy *slaveProxy, const std::string &filePath, const CFileStatus &fileStatus)
: m_Master(master), m_SlaveProxy(slaveProxy), m_FilePath(filePath), m_FileStatus(fileStatus) { }
virtual void run()
{
m_Master->m_SlavesMutex.lock();
TSlaveMap::iterator slaveIt = m_Master->m_Slaves.find(m_SlaveProxy);
if (slaveIt == m_Master->m_Slaves.end())
{
// nlwarning("Slave disconnected before callback could be delivered");
m_Master->m_SlavesMutex.unlock();
delete this;
return;
}
CSlave *slave = slaveIt->second;
m_Master->m_SlavesMutex.unlock();
slave->Proxy.addFileStatusToCache(m_Master, macroPath(m_FilePath), m_FileStatus);
delete this;
}
private:
CModulePipelineMaster *m_Master;
NLNET::IModuleProxy *m_SlaveProxy;
std::string m_FilePath;
CFileStatus m_FileStatus;
};
public: public:
CUpdateDatabaseStatusSlaveCallback(CModulePipelineMaster *master, NLNET::IModuleProxy *slaveProxy) : CDelayedCallback(master), m_SlaveProxy(slaveProxy) { } CUpdateDatabaseStatusSlaveCallback(CModulePipelineMaster *master, NLNET::IModuleProxy *slaveProxy) : CDelayedCallback(master), m_SlaveProxy(slaveProxy) { }
void fileCallback(const std::string &filePath, const CFileStatus &fileStatus, bool success)
{
if (success)
{
Master->addUpdateTask(new CSlaveFileCallback(Master, m_SlaveProxy, filePath, fileStatus));
}
}
/// All status updated for this task
virtual void run() // this is sanely run from the update thread virtual void run() // this is sanely run from the update thread
{ {
Master->m_SlavesMutex.lock(); Master->m_SlavesMutex.lock();
@ -583,7 +626,7 @@ public:
virtual void run() // run from the master process task manager virtual void run() // run from the master process task manager
{ {
CUpdateDatabaseStatusSlaveCallback *cb = new CUpdateDatabaseStatusSlaveCallback(m_Master, m_Sender); // deleted by update CUpdateDatabaseStatusSlaveCallback *cb = new CUpdateDatabaseStatusSlaveCallback(m_Master, m_Sender); // deleted by update
g_DatabaseStatus->updateDatabaseStatus(cb->getCallback(), m_Vector, false, false); g_DatabaseStatus->updateDatabaseStatus(cb->getCallback(), TFileStatusCallback(cb, &CUpdateDatabaseStatusSlaveCallback::fileCallback), m_Vector, false, false);
delete this; delete this;
} }

@ -422,6 +422,8 @@ public:
virtual void addFileStatusToCache(NLNET::IModuleProxy *sender, const std::string &macroPath, const CFileStatus &fileStatus) virtual void addFileStatusToCache(NLNET::IModuleProxy *sender, const std::string &macroPath, const CFileStatus &fileStatus)
{ {
nlassert(sender == NULL || m_Master->getModuleProxy() == sender); // sanity check nlassert(sender == NULL || m_Master->getModuleProxy() == sender); // sanity check
nldebug("Add file status: '%s' (macro path)", macroPath.c_str());
std::string filePath = unMacroPath(macroPath); std::string filePath = unMacroPath(macroPath);
nlassert(m_FileStatusCache.find(filePath) == m_FileStatusCache.end()); nlassert(m_FileStatusCache.find(filePath) == m_FileStatusCache.end());

Loading…
Cancel
Save