resolves #41: strange behaviour of limits

On a configuration change, update existing Nodes in Laminar's NodeMap
rather than replacing it with a new map.
pull/53/head
Oliver Giles 6 years ago
parent c937362961
commit 083f136186

@ -314,9 +314,9 @@ void Laminar::sendStatus(LaminarClient* client) {
int execTotal = 0;
int execBusy = 0;
for(const auto& it : nodes) {
const Node& node = it.second;
execTotal += node.numExecutors;
execBusy += node.busyExecutors;
const std::shared_ptr<Node>& node = it.second;
execTotal += node->numExecutors;
execBusy += node->busyExecutors;
}
j.set("executorsTotal", execTotal);
j.set("executorsBusy", execBusy);
@ -375,7 +375,7 @@ bool Laminar::loadConfiguration() {
if(const char* ndirs = getenv("LAMINAR_KEEP_RUNDIRS"))
numKeepRunDirs = static_cast<uint>(atoi(ndirs));
NodeMap nm;
std::set<std::string> knownNodes;
fs::path nodeCfg = fs::path(homeDir)/"cfg"/"nodes";
@ -386,9 +386,11 @@ bool Laminar::loadConfiguration() {
StringMap conf = parseConfFile(it->path().string().c_str());
Node node;
node.name = it->path().stem().string();
node.numExecutors = conf.get<int>("EXECUTORS", 6);
std::string nodeName = it->path().stem().string();
auto existingNode = nodes.find(nodeName);
std::shared_ptr<Node> node = existingNode == nodes.end() ? nodes.emplace(nodeName, new Node).first->second : existingNode->second;
node->name = nodeName;
node->numExecutors = conf.get<int>("EXECUTORS", 6);
std::string tags = conf.get<std::string>("TAGS");
if(!tags.empty()) {
@ -397,22 +399,29 @@ bool Laminar::loadConfiguration() {
std::string tag;
while(std::getline(iss, tag, ','))
tagList.insert(tag);
node.tags = tagList;
node->tags = tagList;
}
nm.emplace(node.name, std::move(node));
knownNodes.insert(nodeName);
}
}
if(nm.empty()) {
// add a default node
Node node;
node.name = "";
node.numExecutors = 6;
nm.emplace("", std::move(node));
// remove any nodes whose config files disappeared.
// if there are no known nodes, take care not to remove and re-add the default node
for(auto it = nodes.begin(); it != nodes.end();) {
if((it->first == "" && knownNodes.size() == 0) || knownNodes.find(it->first) != knownNodes.end())
it++;
else
it = nodes.erase(it);
}
nodes = nm;
// add a default node
if(nodes.empty()) {
std::shared_ptr<Node> node(new Node);
node->name = "";
node->numExecutors = 6;
nodes.emplace("", node);
}
fs::path jobsDir = fs::path(homeDir)/"cfg"/"jobs";
if(fs::is_directory(jobsDir)) {
@ -571,9 +580,9 @@ void Laminar::assignNewJobs() {
while(it != queuedJobs.end()) {
bool assigned = false;
for(auto& sn : nodes) {
Node& node = sn.second;
std::shared_ptr<Node> node = sn.second;
std::shared_ptr<Run> run = *it;
if(nodeCanQueue(node, *run)) {
if(nodeCanQueue(*node.get(), *run)) {
fs::path cfgDir = fs::path(homeDir)/"cfg";
boost::system::error_code err;
@ -621,8 +630,8 @@ void Laminar::assignNewJobs() {
if(fs::exists(cfgDir/"before"))
run->addScript((cfgDir/"before").string());
// per-node before-run script
if(fs::exists(cfgDir/"nodes"/node.name+".before"))
run->addScript((cfgDir/"nodes"/node.name+".before").string());
if(fs::exists(cfgDir/"nodes"/node->name+".before"))
run->addScript((cfgDir/"nodes"/node->name+".before").string());
// job before-run script
if(fs::exists(cfgDir/"jobs"/run->name+".before"))
run->addScript((cfgDir/"jobs"/run->name+".before").string());
@ -632,8 +641,8 @@ void Laminar::assignNewJobs() {
if(fs::exists(cfgDir/"jobs"/run->name+".after"))
run->addScript((cfgDir/"jobs"/run->name+".after").string());
// per-node after-run script
if(fs::exists(cfgDir/"nodes"/node.name+".after"))
run->addScript((cfgDir/"nodes"/node.name+".after").string());
if(fs::exists(cfgDir/"nodes"/node->name+".after"))
run->addScript((cfgDir/"nodes"/node->name+".after").string());
// global after-run script
if(fs::exists(cfgDir/"after"))
run->addScript((cfgDir/"after").string());
@ -641,14 +650,14 @@ void Laminar::assignNewJobs() {
// add environment files
if(fs::exists(cfgDir/"env"))
run->addEnv((cfgDir/"env").string());
if(fs::exists(cfgDir/"nodes"/node.name+".env"))
run->addEnv((cfgDir/"nodes"/node.name+".env").string());
if(fs::exists(cfgDir/"nodes"/node->name+".env"))
run->addEnv((cfgDir/"nodes"/node->name+".env").string());
if(fs::exists(cfgDir/"jobs"/run->name+".env"))
run->addEnv((cfgDir/"jobs"/run->name+".env").string());
// start the job
node.busyExecutors++;
run->node = &node;
node->busyExecutors++;
run->node = node;
run->startedAt = time(nullptr);
run->laminarHome = homeDir;
run->build = buildNum;
@ -661,7 +670,7 @@ void Laminar::assignNewJobs() {
// update next build number
buildNums[run->name] = buildNum;
LLOG(INFO, "Queued job to node", run->name, run->build, node.name);
LLOG(INFO, "Queued job to node", run->name, run->build, node->name);
// notify clients
Json j;
@ -713,7 +722,7 @@ void Laminar::assignNewJobs() {
}
void Laminar::runFinished(Run * r) {
Node* node = r->node;
std::shared_ptr<Node> node = r->node;
node->busyExecutors--;
LLOG(INFO, "Run completed", r->name, to_string(r->result));

@ -27,7 +27,7 @@
#include <unordered_map>
// Node name to node object map
typedef std::unordered_map<std::string,Node> NodeMap;
typedef std::unordered_map<std::string, std::shared_ptr<Node>> NodeMap;
struct Server;
class Json;

@ -25,6 +25,7 @@
#include <functional>
#include <ostream>
#include <unordered_map>
#include <memory>
enum class RunState {
UNKNOWN,
@ -75,7 +76,7 @@ public:
std::string reason() const;
std::function<void(Run*)> notifyCompletion;
Node* node;
std::shared_ptr<Node> node;
RunState result;
RunState lastResult;
std::string laminarHome;

@ -25,7 +25,7 @@
class RunTest : public ::testing::Test {
protected:
void SetUp() override {
run.node = &node;
run.node = node;
}
void wait() {
int state = -1;
@ -55,7 +55,7 @@ protected:
}
class Run run;
Node node;
std::shared_ptr<Node> node = std::shared_ptr<Node>(new Node);
};
TEST_F(RunTest, WorkingDirectory) {

Loading…
Cancel
Save