Skip to content

Commit

Permalink
implemented generalized __if__
Browse files Browse the repository at this point in the history
  • Loading branch information
mdorier committed Jul 22, 2024
1 parent ba26f0c commit 17307d3
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 27 deletions.
9 changes: 1 addition & 8 deletions src/ClientManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,14 @@ ClientManager::addClientFromJSON(const json& description) {
]
}
},
"config": {"type": "object"},
"__if__": {"type": "string", "minLength":1}
"config": {"type": "object"}
},
"required": ["name", "type"]
}
)"_json;
static const JsonValidator validator{configSchema};
validator.validate(description, "ClientManager");

if(description.contains("__if__")) {
bool b = Jx9Manager(self->m_jx9_manager).evaluateCondition(
description["__if__"].get_ref<const std::string&>(), {});
if(!b) return nullptr;
}

auto& name = description["name"].get_ref<const std::string&>();
auto& type = description["type"].get_ref<const std::string&>();

Expand Down
36 changes: 35 additions & 1 deletion src/JsonUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
#ifndef BEDROCK_JSON_UTIL_H
#define BEDROCK_JSON_UTIL_H

#include <bedrock/DetailedException.hpp>
#include <bedrock/Jx9Manager.hpp>
#include <nlohmann/json.hpp>
#include <nlohmann/json-schema.hpp>
#include <string>
#include <bedrock/DetailedException.hpp>

namespace bedrock {

Expand Down Expand Up @@ -84,6 +85,39 @@ static inline json expandSimplifiedJSON(const json& input) {
return output;
}

static inline json filterIfConditionsInJSON(const json& input, Jx9Manager jx9) {
json output; // null by default
if(input.is_array()) {
output = json::array();
for(auto& item : input) {
auto filteredItem = filterIfConditionsInJSON(item, jx9);
if(filteredItem.is_null()) continue;
output.push_back(filterIfConditionsInJSON(item, jx9));
}
} else if(input.is_object()) {
bool condition = true;
if(input.contains("__if__")) {
auto _if = input["__if__"];
if(_if.is_boolean()) condition = _if.get<bool>();
else if(_if.is_string())
condition = jx9.evaluateCondition(
_if.get_ref<const std::string&>(),
std::unordered_map<std::string, std::string>());
else
throw Exception("__if__ condition should be a string or a boolean");
}
if(condition) {
output = json::object();
for(auto& p : input.items()) {
output[p.key()] = filterIfConditionsInJSON(p.value(), jx9);
}
}
} else {
output = input;
}
return output;
}

}

#endif
14 changes: 5 additions & 9 deletions src/Jx9Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ using nlohmann::json;

// LCOV_EXCL_START

Jx9Manager::Jx9Manager() : self(std::make_shared<Jx9ManagerImpl>()) {}
Jx9Manager::Jx9Manager()
: self(std::make_shared<Jx9ManagerImpl>()) {}

Jx9Manager::Jx9Manager(const Jx9Manager&) = default;

Expand Down Expand Up @@ -71,15 +72,10 @@ std::string Jx9Manager::executeQuery(
// installing MPI_COMM_WORLD
json comm_world = nullptr;
#ifdef ENABLE_MPI
int mpi_rank, mpi_size;
int mpi_initialized;
MPI_Initialized(&mpi_initialized);
if(mpi_initialized) {
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
if(self->m_mpi->enabled()) {
comm_world = json::object();
comm_world["rank"] = mpi_rank;
comm_world["size"] = mpi_size;
comm_world["rank"] = self->m_mpi->rank();
comm_world["size"] = self->m_mpi->size();
}
#endif
jx9_value* jx9_comm_world = nullptr;
Expand Down
5 changes: 4 additions & 1 deletion src/Jx9ManagerImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>
#include <string>
#include <unordered_map>
#include "MPI.hpp"

namespace bedrock {

Expand All @@ -24,8 +25,10 @@ class Jx9ManagerImpl {
jx9* m_engine = nullptr;
tl::mutex m_mtx;
std::unordered_map<std::string, std::string> m_global_variables;
std::shared_ptr<MPI> m_mpi;

Jx9ManagerImpl() {
Jx9ManagerImpl()
: m_mpi(std::make_shared<MPI>()) {
spdlog::trace("Initializing Jx9 engine");
jx9_init(&m_engine);
}
Expand Down
29 changes: 29 additions & 0 deletions src/MPI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifdef ENABLE_MPI
#include <mpi.h>
#endif
#include <bedrock/Exception.hpp>

namespace bedrock {

Expand Down Expand Up @@ -44,6 +45,34 @@ class MPI {
}
s_initialized_mpi = false;
}
#endif
}

bool enabled() const {
#ifdef ENABLE_MPI
return true;
#else
return false;
#endif
}

int size() const {
#ifdef ENABLE_MPI
int s;
MPI_Comm_size(MPI_COMM_WORLD, &s);
return s;
#else
throw Exception("Cannot get size of MPI_COMM_WORLD in a non-MPI deployment");
#endif
}

int rank() const {
#ifdef ENABLE_MPI
int r;
MPI_Comm_rank(MPI_COMM_WORLD, &r);
return r;
#else
throw Exception("Cannot get rank of process in a non-MPI deployment");
#endif
}
};
Expand Down
9 changes: 1 addition & 8 deletions src/ProviderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,14 @@ ProviderManager::addProviderFromJSON(const json& description) {
]
}
},
"config": {"type": "object"},
"__if__": {"type": "string", "minLength":1}
"config": {"type": "object"}
},
"required": ["name", "type"]
}
)"_json;
static const JsonValidator validator{configSchema};
validator.validate(description, "ProviderManager");

if(description.contains("__if__")) {
bool b = Jx9Manager(self->m_jx9_manager).evaluateCondition(
description["__if__"].get_ref<const std::string&>(), {});
if(!b) return nullptr;
}

auto& name = description["name"].get_ref<const std::string&>();
auto& type = description["type"].get_ref<const std::string&>();
auto provider_id = description.value("provider_id", std::numeric_limits<uint16_t>::max());
Expand Down
11 changes: 11 additions & 0 deletions src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ Server::Server(const std::string& address, const std::string& configString,
config = Toml2Json(tomlConfig);
}

// Filter __if__ statements in configuration
config = filterIfConditionsInJSON(config, jx9Manager);

// If the config is an array, it should have only one entry remaining after filtering
if(config.is_array()) {
if(config.size() != 1) {
throw Exception{"Configuration did not resolve to a single possibility"};
}
config = config[0];
}

// Extract margo section from the config
spdlog::trace("Initializing MargoManager");
auto margoConfig = config["margo"].dump();
Expand Down

0 comments on commit 17307d3

Please sign in to comment.