diff --git a/test/pitytest11/src/PityModel.cc b/test/pitytest11/src/PityModel.cc index ba468bf..e6ddaf8 100644 --- a/test/pitytest11/src/PityModel.cc +++ b/test/pitytest11/src/PityModel.cc @@ -10,13 +10,11 @@ namespace pEp { namespace PityTest11 { bool PityModel::debug_log_enabled = false; - PityModel::PityModel(const std::string& name, int nodeCount) : - _name{ name }, _unit{ nullptr, name, nullptr, this } + PityModel::PityModel(const std::string& name, int nodeCount) : _name{ name } { for (int i = 0; i < nodeCount; i++) { - _nodes.emplace_back(std::make_shared(*this, i)); + _nodes.emplace_back(std::make_shared(i)); } - } std::string PityModel::getName() const @@ -24,105 +22,96 @@ namespace pEp { return _name; } - void PityModel::setName(std::string name) - { - _name = name; - } +// void PityModel::setName(std::string name) +// { +// _name = name; +// } std::vector> PityModel::nodes() const { return _nodes; } - PityUnit& PityModel::unit() - { - return _unit; - } - - PityUnit* PityModel::unitOfNodeNr(int nr) const - { - return nodes().at(nr)->unit().get(); - } + // PityUnit* PityModel::unitOfNodeNr(int nr) const + // { + // return nodes().at(nr)->unit().get(); + // } PityNode* PityModel::nodeNr(int nr) const { return nodes().at(nr).get(); } - void PityModel::run() - { - unit().run(); - } - - void PityModel::sendMsg(const std::string nodename, const std::string& msg) const - { - pEpLogClass("Address: " + nodename + " msg: " + msg); - bool found = false; - for (auto n : _nodes) { - if (n->getName() == nodename) { - found = true; - Utils::dir_ensure(n->inboxDir()); - std::stringstream filename; - // collision detect - do { - filename << n->inboxDir() << Utils::random_string(97, 122, 16) << ".pitymsg"; - } while (Utils::path_exists(filename.str())); - std::ofstream msgfile = Utils::file_create(filename.str()); - msgfile << msg; - } - } - if (!found) { - throw std::runtime_error("no such nodename: " + nodename); - } - } - - bool PityModel::hasMsg() const{ - bool ret = false; - pEpLogClass("called"); - Utils::dir_ensure(own_node->inboxDir()); - auto msg_filenames = Utils::dir_list_files(own_node->inboxDir()); - ret = msg_filenames.size() > 0; - return ret; - } - - // Non-blocking - // throws underflow_error if inbox empty - std::string PityModel::pollMsg() const - { - pEpLogClass("called"); - std::string ret; - Utils::dir_ensure(own_node->inboxDir()); - auto msg_filenames = Utils::dir_list_files(own_node->inboxDir()); - if (!msg_filenames.empty()) { - std::string msg_filename = msg_filenames.at(0); - std::string msg_path = own_node->inboxDir() + "/" + msg_filename; - pEpLogClass("Reading file: " + msg_filename); - ret = Utils::file_read(msg_path); - Utils::path_delete(msg_path); - } else { - throw std::underflow_error("inbox empty: " + own_node->inboxDir()); - } - - return ret; - } - std::string PityModel::receiveMsg(int timeout_msec) const - { - pEpLogClass("called"); - std::string ret; - bool retry = false; - do { - try { - ret = pollMsg(); - retry = false; - } catch (const std::underflow_error&) { - pEpLogClass("polling again in [ms]: " + std::to_string(timeout_msec) + "..."); - Utils::sleep_millis(timeout_msec); - retry = true; - } - } while (retry); - return ret; - } + // void PityModel::sendMsg(const std::string nodename, const std::string& msg) const + // { + // pEpLogClass("Address: " + nodename + " msg: " + msg); + // bool found = false; + // for (auto n : _nodes) { + // if (n->getName() == nodename) { + // found = true; + // Utils::dir_ensure(n->inboxDir()); + // std::stringstream filename; + // // collision detect + // do { + // filename << n->inboxDir() << Utils::random_string(97, 122, 16) << ".pitymsg"; + // } while (Utils::path_exists(filename.str())); + // std::ofstream msgfile = Utils::file_create(filename.str()); + // msgfile << msg; + // } + // } + // if (!found) { + // throw std::runtime_error("no such nodename: " + nodename); + // } + // } + // + // bool PityModel::hasMsg() const{ + // bool ret = false; + // pEpLogClass("called"); + // Utils::dir_ensure(own_node->inboxDir()); + // auto msg_filenames = Utils::dir_list_files(own_node->inboxDir()); + // ret = msg_filenames.size() > 0; + // return ret; + // } + // + // // Non-blocking + // // throws underflow_error if inbox empty + // std::string PityModel::pollMsg() const + // { + // pEpLogClass("called"); + // std::string ret; + // Utils::dir_ensure(own_node->inboxDir()); + // auto msg_filenames = Utils::dir_list_files(own_node->inboxDir()); + // if (!msg_filenames.empty()) { + // std::string msg_filename = msg_filenames.at(0); + // std::string msg_path = own_node->inboxDir() + "/" + msg_filename; + // pEpLogClass("Reading file: " + msg_filename); + // ret = Utils::file_read(msg_path); + // Utils::path_delete(msg_path); + // } else { + // throw std::underflow_error("inbox empty: " + own_node->inboxDir()); + // } + // + // return ret; + // } + // + // std::string PityModel::receiveMsg(int timeout_msec) const + // { + // pEpLogClass("called"); + // std::string ret; + // bool retry = false; + // do { + // try { + // ret = pollMsg(); + // retry = false; + // } catch (const std::underflow_error&) { + // pEpLogClass("polling again in [ms]: " + std::to_string(timeout_msec) + "..."); + // Utils::sleep_millis(timeout_msec); + // retry = true; + // } + // } while (retry); + // return ret; + // } } // namespace PityTest11 } // namespace pEp diff --git a/test/pitytest11/src/PityModel.hh b/test/pitytest11/src/PityModel.hh index aa9cb8a..07929b7 100644 --- a/test/pitytest11/src/PityModel.hh +++ b/test/pitytest11/src/PityModel.hh @@ -38,8 +38,8 @@ namespace pEp { // Getters std::string getName() const; std::vector> nodes() const; - PityUnit& unit(); - PityUnit* unitOfNodeNr(int nr) const; +// PityUnit& unit(); +// PityUnit* unitOfNodeNr(int nr) const; PityNode* nodeNr(int nr) const; // Setter @@ -48,21 +48,17 @@ namespace pEp { // Perspective PityNode* own_node = nullptr; - //Run - void run(); - //Transport - bool hasMsg() const; - void sendMsg(const std::string nodename, const std::string& msg) const; - std::string pollMsg() const; - std::string receiveMsg(int timeout_msec = 100) const; +// bool hasMsg() const; +// void sendMsg(const std::string nodename, const std::string& msg) const; +// std::string pollMsg() const; +// std::string receiveMsg(int timeout_msec = 100) const; //internal logging static bool debug_log_enabled; Adapter::pEpLog::pEpLogger logger_debug{ "PityModel", debug_log_enabled }; private: - PityUnit _unit; std::vector> _nodes; std::string _name; diff --git a/test/pitytest11/src/PityNode.cc b/test/pitytest11/src/PityNode.cc index 03434e6..1a29dae 100644 --- a/test/pitytest11/src/PityNode.cc +++ b/test/pitytest11/src/PityNode.cc @@ -1,6 +1,7 @@ #include "PityModel.hh" #include "PityNode.hh" #include "PityUnit.hh" +#include "PityPerspective.hh" #include "iostream" #include #include @@ -11,39 +12,17 @@ namespace pEp { namespace PityTest11 { bool PityNode::debug_log_enabled = false; - PityNode::PityNode(PityModel& model, int nodeNr) : _node_nr{ nodeNr } + PityNode::PityNode(int nodeNr) : _node_nr{ nodeNr } { logger_debug.set_instancename(getName()); std::stringstream ss{}; ss << this; pEpLogClass(std::string("called with: " + std::to_string(_node_nr) + "AT: " + ss.str())); - - _unit = std::make_shared>( - &(model.unit()), - getName(), - std::bind(&PityNode::_init, this, std::placeholders::_1), - &model, - PityUnit::ExecutionMode::PROCESS_PARALLEL); } - // We NEED to customize (perspective) the model here - // This will be executed in the new process - void PityNode::_init(const PityUnit& unit) + int PityNode::getNr() const { - unit.log("NODE INIT - " + getName()); - unit.getModel()->own_node = this; - unit.getModel()->setName("Copy for:" + getName()); - - _partnerAlgo_NextCircle(); - - // Create peers, everyone but me - auto nodes = _unit->getModel()->nodes(); - for (int i = 0; i < nodes.size(); i++) { - if (i != _node_nr) { - peers.push_back(nodes.at(i)->getName()); - } - } - unit.log("NODE INIT DONE"); + return _node_nr; } std::string PityNode::getName() const @@ -59,21 +38,5 @@ namespace pEp { ret += "name: " + getName(); return ret; } - - const std::shared_ptr>& PityNode::unit() const - { - return _unit; - } - - std::string PityNode::inboxDir() const - { - return unit()->processDir() + "inbox/"; - } - - void PityNode::_partnerAlgo_NextCircle() { - // Default partner is next node, its a circle - int partner_node_index = (_node_nr+1) % _unit->getModel()->nodes().size(); - partner = unit()->getModel()->nodes().at(partner_node_index)->getName(); - } } // namespace PityTest11 } // namespace pEp diff --git a/test/pitytest11/src/PityNode.hh b/test/pitytest11/src/PityNode.hh index 5d7ce50..ef5db16 100644 --- a/test/pitytest11/src/PityNode.hh +++ b/test/pitytest11/src/PityNode.hh @@ -7,6 +7,7 @@ #include "../../../src/pEpLog.hh" #include "PityUnit.hh" #include "PityModel.hh" +#include "PityPerspective.hh" namespace pEp { namespace PityTest11 { @@ -15,18 +16,12 @@ namespace pEp { public: // Constructors PityNode() = delete; - explicit PityNode(PityModel& model, int nodeNr); + explicit PityNode(int nodeNr); // Getters + int getNr() const; std::string getName() const; std::string to_string() const; - const std::shared_ptr>& unit() const; - std::string inboxDir() const; - - // Perspective - std::string partner; - std::vector peers; - //internal logging static bool debug_log_enabled; @@ -35,12 +30,6 @@ namespace pEp { private: //fields const int _node_nr; - std::shared_ptr> _unit; - - // methods - void _init(const PityUnit& unit); - void _partnerAlgo_NextCircle(); - //internal logging Adapter::pEpLog::pEpLogger& m4gic_logger_n4me = logger_debug; diff --git a/test/pitytest11/src/PitySwarm.cc b/test/pitytest11/src/PitySwarm.cc new file mode 100644 index 0000000..7bb21ca --- /dev/null +++ b/test/pitytest11/src/PitySwarm.cc @@ -0,0 +1,83 @@ +#include "PityModel.hh" +#include "PityUnit.hh" +#include "PitySwarm.hh" + +#include +#include +#include + +namespace pEp { + namespace PityTest11 { + bool PitySwarm::debug_log_enabled = false; + + void createPerspective(const PityModel& model, PityPerspective* psp, int node_nr) + { + psp->name = model.nodeNr(node_nr)->getName(); + + // Default partner is next node, its a circle + int partner_node_index = (node_nr + 1) % model.nodes().size(); + psp->partner = model.nodes().at(partner_node_index)->getName(); + + // Create peers, everyone but me + auto nodes = model.nodes(); + for (int i = 0; i < nodes.size(); i++) { + if (i != node_nr) { + psp->peers.push_back(nodes.at(i)->getName()); + } + } + } + + PitySwarm::PitySwarm(PityModel& model) : _model{ model } + { + pEpLogClass("called"); + // Create perspective + for (auto n : _model.nodes()) { + auto tmp = std::make_shared(); + createPerspective(_model, tmp.get(), n->getNr()); + _perspectives.push_back(tmp); + } + + // Construct Tree + _rootUnit = std::make_shared>( + nullptr, + _model.getName(), + nullptr, + &_model); + + for (auto n : _model.nodes()) { + _nodeUnits.push_back(std::make_shared>( + _rootUnit.get(), + n->getName(), + nullptr, + // std::bind( + // &PityNode::_init, + // this, + // std::placeholders::_1, + // std::placeholders::_2, + // std::placeholders::_3), + &_model, + _perspectives.at(n->getNr()).get(), + PityUnit<>::ExecutionMode::PROCESS_PARALLEL)); + } + } + + void PitySwarm::addTestUnit( + int nodeNr, + const std::string& name, + std::function&, PityModel*, PityPerspective*)> test_func) + { + auto tmp = std::make_shared >(_nodeUnits.at(nodeNr).get(), name, test_func); + _testUnits.push_back(tmp); + } + + + + void PitySwarm::run() + { + + _rootUnit->run(); + } + + + } // namespace PityTest11 +} // namespace pEp diff --git a/test/pitytest11/src/PitySwarm.hh b/test/pitytest11/src/PitySwarm.hh new file mode 100644 index 0000000..0bd9c26 --- /dev/null +++ b/test/pitytest11/src/PitySwarm.hh @@ -0,0 +1,46 @@ +// This file is under GNU General Public License 3.0 +// see LICENSE.txt + +#ifndef PITYTEST_PITYSWARM_HH +#define PITYTEST_PITYSWARM_HH + +#include "PityModel.hh" +#include "PityUnit.hh" +#include "../../../src/pEpLog.hh" +#include +#include +#include + +namespace pEp { + namespace PityTest11 { + class PitySwarm { + public: + // Constructors + PitySwarm(PityModel& model); + + void addTestUnit( + int nodeNr, + const std::string& name, + std::function&, PityModel*, PityPerspective*)> test_func); + + //Run + void run(); + + //internal logging + static bool debug_log_enabled; + Adapter::pEpLog::pEpLogger logger_debug{ "PityNode", debug_log_enabled }; + + private: + PityModel& _model; + std::shared_ptr> _rootUnit; + std::vector>> _nodeUnits; + std::vector>> _testUnits; + std::vector> _perspectives; + + //internal logging + Adapter::pEpLog::pEpLogger& m4gic_logger_n4me = logger_debug; + }; + }; // namespace PityTest11 +}; // namespace pEp + +#endif // PITYTEST_PITYSWARM_HH