ensuring no duplicate rx hostname port combo (#604)

* rx_hostname and port combo to one, or hostname to all, or a vector of hostnames and ports, ignoring none or empty, then verifying no duplicates for the host port combo including from shared memory

* extracted function for rx_hostname (#694)

* c++14 revert

* unique hostname-port combo for port, hostname, rx_tcpport (#696)

* verify unique combo for rx_port as well

* check unique hostname-port combo also when setting control port, hostname, rx_hostname and rx_tcpport

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
Co-authored-by: Erik Frojdh <erik.frojdh@psi.ch>
This commit is contained in:
Dhanya Thattil
2023-03-20 12:30:12 +01:00
committed by GitHub
parent c9215a6d9b
commit b67c6dea08
11 changed files with 228 additions and 44 deletions

View File

@ -279,31 +279,14 @@ void DetectorImpl::setHostname(const std::vector<std::string> &name) {
}
}
void DetectorImpl::addModule(const std::string &hostname) {
LOG(logINFO) << "Adding module " << hostname;
int port = DEFAULT_TCP_CNTRL_PORTNO;
std::string host = hostname;
auto res = split(hostname, ':');
if (res.size() > 1) {
host = res[0];
port = StringTo<int>(res[1]);
}
if (host != "localhost") {
for (auto &module : modules) {
if (module->getHostname() == host) {
LOG(logWARNING)
<< "Module " << host << "already part of the Detector!"
<< std::endl
<< "Remove it before adding it back in a new position!";
return;
}
}
}
void DetectorImpl::addModule(const std::string &name) {
LOG(logINFO) << "Adding module " << name;
auto host = verifyUniqueDetHost(name);
std::string hostname = host.first;
int port = host.second;
// get type by connecting
detectorType type = Module::getTypeFromDetector(host, port);
detectorType type = Module::getTypeFromDetector(hostname, port);
// gotthard cannot have more than 2 modules (50um=1, 25um=2
if ((type == GOTTHARD || type == GOTTHARD2) && modules.size() > 2) {
@ -316,7 +299,7 @@ void DetectorImpl::addModule(const std::string &hostname) {
shm()->totalNumberOfModules = modules.size();
modules[pos]->setControlPort(port);
modules[pos]->setStopPort(port + 1);
modules[pos]->setHostname(host, shm()->initialChecks);
modules[pos]->setHostname(hostname, shm()->initialChecks);
// module type updated by now
shm()->detType = Parallel(&Module::getDetectorType, {})
@ -1538,6 +1521,129 @@ defs::xy DetectorImpl::calculatePosition(int moduleIndex,
return pos;
}
void DetectorImpl::verifyUniqueDetHost(const int port,
std::vector<int> positions) const {
// port for given positions
if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
std::vector<std::pair<std::string, int>> hosts(size());
for (auto it : positions) {
hosts[it].second = port;
}
verifyUniqueHost(true, hosts);
}
void DetectorImpl::verifyUniqueRxHost(const int port,
const int moduleId) const {
std::vector<std::pair<std::string, int>> hosts(size());
hosts[moduleId].second = port;
verifyUniqueHost(false, hosts);
}
std::pair<std::string, int>
DetectorImpl::verifyUniqueDetHost(const std::string &name) {
// extract port
// C++17 could be auto [hostname, port] = ParseHostPort(name);
auto res = ParseHostPort(name);
std::string hostname = res.first;
int port = res.second;
if (port == 0) {
port = DEFAULT_TCP_CNTRL_PORTNO;
}
int detSize = size();
// mod not yet added
std::vector<std::pair<std::string, int>> hosts(detSize + 1);
hosts[detSize].first = hostname;
hosts[detSize].second = port;
verifyUniqueHost(true, hosts);
return std::make_pair(hostname, port);
}
std::pair<std::string, int>
DetectorImpl::verifyUniqueRxHost(const std::string &name,
std::vector<int> positions) const {
// no checks if setting to none
if (name == "none" || name.empty()) {
return make_pair(name, 0);
}
// extract port
// C++17 could be auto [hostname, port] = ParseHostPort(name);
auto res = ParseHostPort(name);
std::string hostname = res.first;
int port = res.second;
// hostname and port for given positions
if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
std::vector<std::pair<std::string, int>> hosts(size());
for (auto it : positions) {
hosts[it].first = hostname;
hosts[it].second = port;
}
verifyUniqueHost(false, hosts);
return std::make_pair(hostname, port);
}
std::vector<std::pair<std::string, int>>
DetectorImpl::verifyUniqueRxHost(const std::vector<std::string> &names) const {
if ((int)names.size() != size()) {
throw RuntimeError(
"Receiver hostnames size " + std::to_string(names.size()) +
" does not match detector size " + std::to_string(size()));
}
// extract ports
std::vector<std::pair<std::string, int>> hosts;
for (const auto &name : names) {
hosts.push_back(ParseHostPort(name));
}
verifyUniqueHost(false, hosts);
return hosts;
}
void DetectorImpl::verifyUniqueHost(
bool isDet, std::vector<std::pair<std::string, int>> &hosts) const {
// fill from shm if not provided
for (int i = 0; i != size(); ++i) {
if (hosts[i].first.empty()) {
hosts[i].first = (isDet ? modules[i]->getHostname()
: modules[i]->getReceiverHostname());
}
if (hosts[i].second == 0) {
hosts[i].second = (isDet ? modules[i]->getControlPort()
: modules[i]->getReceiverPort());
}
}
// remove the ones without a hostname
hosts.erase(std::remove_if(hosts.begin(), hosts.end(),
[](const std::pair<std::string, int> &x) {
return (x.first == "none" ||
x.first.empty());
}),
hosts.end());
// must be unique
if (hasDuplicates(hosts)) {
throw RuntimeError(
"Cannot set due to duplicate hostname-port number pairs.");
}
for (auto it : hosts) {
LOG(logDEBUG) << it.first << " " << it.second << std::endl;
}
}
defs::ROI DetectorImpl::getRxROI() const {
if (shm()->detType == CHIPTESTBOARD) {
throw RuntimeError("RxRoi not implemented for this Detector");