diff --git a/code/nel/tools/pipeline/service/example_cfg/pipeline_service_default.cfg b/code/nel/tools/pipeline/service/example_cfg/pipeline_service_default.cfg index 566dea097..4f77f1b77 100644 --- a/code/nel/tools/pipeline/service/example_cfg/pipeline_service_default.cfg +++ b/code/nel/tools/pipeline/service/example_cfg/pipeline_service_default.cfg @@ -61,7 +61,7 @@ DisplayedVariables = { "Status|pipelineServiceState", "FileQueue|asyncFileQueueCount", "", "InfoFlags|infoFlags", - "", "@Reload Sheets|reloadSheets", "@Busy Test|busyTestState" , + "", "@Reload Sheets|reloadSheets", "@Busy Test|busyTestState" , "@Plug Slave|slave.plug gw", "@Unplug Slave|slave.unplug gw", }; DontUseAES = 1; diff --git a/code/nel/tools/pipeline/service/example_cfg/pipeline_service_master.cfg b/code/nel/tools/pipeline/service/example_cfg/pipeline_service_master.cfg index ff329f7d2..3d8026e5d 100644 --- a/code/nel/tools/pipeline/service/example_cfg/pipeline_service_master.cfg +++ b/code/nel/tools/pipeline/service/example_cfg/pipeline_service_master.cfg @@ -23,5 +23,5 @@ StartCommands += DisplayedVariables += { - "", "@Master Reload Sheets|master.reloadSheets", "@Status Update All|updateDatabaseStatus", + "", "@Build|master.build", "@Verify|master.build --verifyOnly", "@Abort|master.abort", "@Master Reload Sheets|master.reloadSheets", "@Status Update All|updateDatabaseStatus", "@Plug Master|master.plug gw", "@Unplug Master|master.unplug gw", }; diff --git a/code/nel/tools/pipeline/service/module_pipeline_master.cpp b/code/nel/tools/pipeline/service/module_pipeline_master.cpp index 8a6cab7d3..c10211df7 100644 --- a/code/nel/tools/pipeline/service/module_pipeline_master.cpp +++ b/code/nel/tools/pipeline/service/module_pipeline_master.cpp @@ -41,6 +41,7 @@ #include "pipeline_service.h" #include "database_status.h" #include "build_task_queue.h" +#include "pipeline_workspace.h" using namespace std; using namespace NLMISC; @@ -126,6 +127,9 @@ public: virtual ~CModulePipelineMaster() { + if (m_BuildWorking) + this->abort(); + g_IsMaster = false; m_SlavesMutex.lock(); @@ -158,6 +162,8 @@ public: m_Slaves[moduleProxy] = slave; m_SlavesMutex.unlock(); + + slave->Proxy.submitToMaster(this); } } @@ -222,6 +228,13 @@ public: it->second->ActiveTaskId = taskInfo->Id.Global; it->second->Proxy.startBuildTask(this, taskInfo->ProjectName, taskInfo->ProcessPluginId); // the slave may either reject; or not answer until it's finished with this task + // Display information to user terminals + { + // TODO_TERMINAL_SYNC + CProcessPluginInfo pluginInfo; + g_PipelineWorkspace->getProcessPlugin(pluginInfo, taskInfo->ProcessPluginId); + nlinfo("Dispatching task '%i' ('%s': '%s') to slave '%s'", taskInfo->Id.Global, taskInfo->ProjectName.c_str(), pluginInfo.Handler.c_str(), it->second->Proxy.getModuleProxy()->getModuleName().c_str()); + } } } } @@ -243,7 +256,7 @@ public: } m_SlavesMutex.unlock(); - PIPELINE::endedBuildReady(); + PIPELINE::endedBuildReadyMaster(); } } } @@ -262,7 +275,10 @@ public: virtual void slaveRefusedBuildTask(NLNET::IModuleProxy *sender) { // TODO + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'slaveRefusedBuildTask' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); m_BuildTaskQueue.rejectedTask(slave->ActiveTaskId); slave->ActiveTaskId = 0; --slave->SaneBehaviour; @@ -272,20 +288,29 @@ public: virtual void slaveReloadedSheets(NLNET::IModuleProxy *sender) { + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'slaveReloadedSheets' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); slave->SheetsOk = true; CInfoFlags::getInstance()->removeFlag(PIPELINE_INFO_MASTER_RELOAD_SHEETS); } virtual void slaveBuildReadySuccess(NLNET::IModuleProxy *sender) { + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'slaveBuildReadySuccess' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); slave->BuildReadyState = 2; } virtual void slaveBuildReadyFail(NLNET::IModuleProxy *sender) { + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'slaveBuildReadyFail' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); slave->BuildReadyState = 0; --slave->SaneBehaviour; CInfoFlags::getInstance()->addFlag(PIPELINE_INFO_SLAVE_REJECTED); @@ -293,13 +318,19 @@ public: virtual void vectorPushString(NLNET::IModuleProxy *sender, const std::string &str) { + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'vectorPushString' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); slave->Vector.push_back(str); } virtual void updateDatabaseStatusByVector(NLNET::IModuleProxy *sender) { + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'updateDatabaseStatusByVector' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); CInfoFlags::getInstance()->addFlag(PIPELINE_INFO_MASTER_UPDATE_DATABASE_FOR_SLAVE); bool ok = true; @@ -325,13 +356,16 @@ public: void setAvailablePlugins(NLNET::IModuleProxy *sender, const std::vector &pluginsAvailable) { + //m_SlavesMutex.lock(); CSlave *slave = m_Slaves[sender]; + if (slave == NULL) { nlerror("Received 'setAvailablePlugins' from unknown slave at '%s'", sender->getModuleName().c_str()); m_Slaves.erase(sender); /*m_SlavesMutex.unlock();*/ return; } + //m_SlavesMutex.unlock(); slave->PluginsAvailable = pluginsAvailable; } bool build(bool bypassEros, bool verifyOnly) { - if (PIPELINE::tryBuildReady()) + if (PIPELINE::tryBuildReadyMaster()) { m_BuildWorking = true; m_BypassErrors = bypassEros; @@ -345,18 +379,25 @@ public: bool abort() { - m_BuildTaskQueue.abortQueue(); + if (m_BuildWorking) + { + m_BuildTaskQueue.abortQueue(); - m_SlavesMutex.lock(); - // Abort all slaves. - for (TSlaveMap::iterator it = m_Slaves.begin(), end = m_Slaves.end(); it != end; ++it) + m_SlavesMutex.lock(); + // Abort all slaves. + for (TSlaveMap::iterator it = m_Slaves.begin(), end = m_Slaves.end(); it != end; ++it) + { + if (it->second->ActiveTaskId != 0) + it->second->Proxy.abortBuildTask(this); + } + m_SlavesMutex.unlock(); + + return true; + } + else { - if (it->second->ActiveTaskId != 0) - it->second->Proxy.abortBuildTask(this); + return false; } - m_SlavesMutex.unlock(); - - return true; } protected: @@ -429,14 +470,30 @@ protected: } else { - return build(bypassErrors, verifyOnly); + if (build(bypassErrors, verifyOnly)) + { + return true; + } + else + { + log.displayNL("Bad command usage"); + return false; + } } } NLMISC_CLASS_COMMAND_DECL(abort) { if (args.size() != 0) return false; - return this->abort(); + if (this->abort()) + { + return true; + } + else + { + log.displayNL("Bad command usage"); + return false; + } } }; /* class CModulePipelineMaster */ diff --git a/code/nel/tools/pipeline/service/module_pipeline_slave.cpp b/code/nel/tools/pipeline/service/module_pipeline_slave.cpp index df1cfaa10..440e57c9a 100644 --- a/code/nel/tools/pipeline/service/module_pipeline_slave.cpp +++ b/code/nel/tools/pipeline/service/module_pipeline_slave.cpp @@ -70,16 +70,20 @@ public: CModulePipelineMasterProxy *m_Master; bool m_TestCommand; TRequestState m_ReloadSheetsState; + bool m_BuildReadyState; public: - CModulePipelineSlave() : m_Master(NULL), m_TestCommand(false), m_ReloadSheetsState(REQUEST_NONE) + CModulePipelineSlave() : m_Master(NULL), m_TestCommand(false), m_ReloadSheetsState(REQUEST_NONE), m_BuildReadyState(false) { } virtual ~CModulePipelineSlave() { - + // TODO: IF MASTER STILL CONNECTED, NOTIFY INSANITY + // TODO: ABORT RUNNING BUILD PROCESS + abortBuildTask(NULL); + leaveBuildReadyState(NULL); } virtual bool initModule(const TParsedCommandLine &initInfo) @@ -98,11 +102,15 @@ public: nlassert(m_Master == NULL); m_Master = new CModulePipelineMasterProxy(moduleProxy); - - // TODO: AUTHENTICATE OR GATEWAY SECURITY? - sendMasterAvailablePlugins(); } } + + virtual void submitToMaster(NLNET::IModuleProxy *sender) + { + // TODO: AUTHENTICATE OR GATEWAY SECURITY? + CModulePipelineMasterProxy master(sender); + sendMasterAvailablePlugins(&master); + } virtual void onModuleDown(IModuleProxy *moduleProxy) { @@ -113,6 +121,8 @@ public: nlassert(m_Master->getModuleProxy() == moduleProxy); // TODO: ABORT RUNNING BUILD PROCESS + abortBuildTask(NULL); + leaveBuildReadyState(NULL); // leave state if building delete m_Master; m_Master = NULL; @@ -133,7 +143,7 @@ public: if (PIPELINE::isServiceStateIdle()) { m_ReloadSheetsState = REQUEST_NONE; - sendMasterAvailablePlugins(); + sendMasterAvailablePlugins(m_Master); m_Master->slaveReloadedSheets(this); CInfoFlags::getInstance()->removeFlag(PIPELINE_INFO_SLAVE_RELOAD_SHEETS); } @@ -175,8 +185,9 @@ public: virtual void enterBuildReadyState(NLNET::IModuleProxy *sender) { - if (PIPELINE::tryBuildReady()) + if (!m_BuildReadyState && PIPELINE::tryBuildReady()) { + m_BuildReadyState = true; m_Master->slaveBuildReadySuccess(this); } else @@ -187,14 +198,18 @@ public: virtual void leaveBuildReadyState(NLNET::IModuleProxy *sender) { - PIPELINE::endedBuildReady(); + if (m_BuildReadyState) + { + m_BuildReadyState = false; + PIPELINE::endedBuildReady(); + } } - void sendMasterAvailablePlugins() + void sendMasterAvailablePlugins(CModulePipelineMasterProxy *master) { std::vector availablePlugins; g_PipelineWorkspace->listAvailablePlugins(availablePlugins); - m_Master->setAvailablePlugins(this, availablePlugins); + master->setAvailablePlugins(this, availablePlugins); } protected: diff --git a/code/nel/tools/pipeline/service/module_pipeline_slave_itf.cpp b/code/nel/tools/pipeline/service/module_pipeline_slave_itf.cpp index e7c621b2b..e0a17d2d5 100644 Binary files a/code/nel/tools/pipeline/service/module_pipeline_slave_itf.cpp and b/code/nel/tools/pipeline/service/module_pipeline_slave_itf.cpp differ diff --git a/code/nel/tools/pipeline/service/module_pipeline_slave_itf.h b/code/nel/tools/pipeline/service/module_pipeline_slave_itf.h index b9698c4f3..ec6151eb2 100644 Binary files a/code/nel/tools/pipeline/service/module_pipeline_slave_itf.h and b/code/nel/tools/pipeline/service/module_pipeline_slave_itf.h differ diff --git a/code/nel/tools/pipeline/service/module_pipeline_slave_itf.xml b/code/nel/tools/pipeline/service/module_pipeline_slave_itf.xml index 8e7a40a7b..8e2c8685c 100644 --- a/code/nel/tools/pipeline/service/module_pipeline_slave_itf.xml +++ b/code/nel/tools/pipeline/service/module_pipeline_slave_itf.xml @@ -4,6 +4,10 @@ + + + + diff --git a/code/nel/tools/pipeline/service/pipeline_service.cpp b/code/nel/tools/pipeline/service/pipeline_service.cpp index dd7622b16..06deff3fc 100644 --- a/code/nel/tools/pipeline/service/pipeline_service.cpp +++ b/code/nel/tools/pipeline/service/pipeline_service.cpp @@ -261,6 +261,36 @@ void endedDirectTask() endedRunnableTask(STATE_DIRECT_CODE); } +bool tryBuildReadyMaster() +{ + bool result = false; + s_StateMutex.enter(); + result = (s_State == STATE_IDLE); + if (result) + { + s_State = STATE_BUILD_READY; + ++s_BuildReadyRecursive; + } + s_StateMutex.leave(); + if (!result) return false; + + nlassert((s_State == STATE_BUILD_READY) && (s_BuildReadyRecursive > 0)); + + return true; +} + +void endedBuildReadyMaster() +{ + nlassert((s_State == STATE_BUILD_READY) && (s_BuildReadyRecursive > 0)); + + s_StateMutex.enter(); + --s_BuildReadyRecursive; + s_State = STATE_IDLE; + s_StateMutex.leave(); + + nlassert(s_BuildReadyRecursive == 0); +} + bool tryBuildReady() { bool result = false; @@ -275,14 +305,14 @@ bool tryBuildReady() s_StateMutex.leave(); if (!result) return false; - nlassert(s_State == STATE_BUILD_READY && s_BuildReadyRecursive > 0); + nlassert((s_State == STATE_BUILD_READY) && (s_BuildReadyRecursive > 0)); return true; } void endedBuildReady() { - nlassert(s_State == STATE_BUILD_READY && s_BuildReadyRecursive > 0); + nlassert((s_State == STATE_BUILD_READY) && (s_BuildReadyRecursive > 0)); s_StateMutex.enter(); --s_BuildReadyRecursive; diff --git a/code/nel/tools/pipeline/service/pipeline_service.h b/code/nel/tools/pipeline/service/pipeline_service.h index 17eae011b..7fc1cc237 100644 --- a/code/nel/tools/pipeline/service/pipeline_service.h +++ b/code/nel/tools/pipeline/service/pipeline_service.h @@ -76,6 +76,9 @@ void endedDirectTask(); bool tryBuildReady(); void endedBuildReady(); +bool tryBuildReadyMaster(); +void endedBuildReadyMaster(); + bool tryBuildProcess(const std::string &stateName); void endedBuildProcess(); diff --git a/code/ryzom/common/data_leveldesign/leveldesign/pipeline/plugin_nel.pipeline_plugin b/code/ryzom/common/data_leveldesign/leveldesign/pipeline/plugin_nel.pipeline_plugin index 2da04f246..f5b9af41c 100644 --- a/code/ryzom/common/data_leveldesign/leveldesign/pipeline/plugin_nel.pipeline_plugin +++ b/code/ryzom/common/data_leveldesign/leveldesign/pipeline/plugin_nel.pipeline_plugin @@ -12,9 +12,7 @@ - - - +