| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************** | ||
| 2 | Auteur : Pierre Aubert | ||
| 3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
| 4 | Licence : CeCILL-C | ||
| 5 | ****************************************/ | ||
| 6 | |||
| 7 | #include <cmath> //for std::nan | ||
| 8 | #include "BaseDaemon.h" | ||
| 9 | #include "PTimer.h" | ||
| 10 | |||
| 11 | ///Default constructor of BaseDaemon | ||
| 12 | 46 | BaseDaemon::BaseDaemon() | |
| 13 |
3/3✓ Branch 0 (5→6) taken 46 times.
✓ Branch 2 (6→7) taken 46 times.
✓ Branch 4 (7→8) taken 46 times.
|
46 | :p_optionParser(true, __PROGRAM_VERSION__) |
| 14 | { | ||
| 15 |
1/1✓ Branch 0 (12→13) taken 46 times.
|
46 | initialisationBaseDaemon(); |
| 16 | 46 | } | |
| 17 | |||
| 18 | ///Destructor of BaseDaemon | ||
| 19 | 46 | BaseDaemon::~BaseDaemon(){ | |
| 20 | 46 | clearCallableMethod(); | |
| 21 | 46 | } | |
| 22 | |||
| 23 | ///Parse arguments given to the BaseDaemon with command line | ||
| 24 | /** @param argc : number of arguments given to the program | ||
| 25 | * @param argv : list of arguments given to the program | ||
| 26 | * @return true on success, false otherwise | ||
| 27 | */ | ||
| 28 | 4 | bool BaseDaemon::parseArgument(int argc, char** argv){ | |
| 29 |
1/1✓ Branch 0 (2→3) taken 4 times.
|
4 | p_optionParser.parseArgument(argc, argv); |
| 30 |
1/1✓ Branch 0 (3→4) taken 4 times.
|
4 | const OptionMode & defaultMode = p_optionParser.getDefaultMode(); |
| 31 |
1/1✓ Branch 0 (4→5) taken 4 times.
|
4 | PPath configurationFile; |
| 32 |
2/2✓ Branch 0 (5→6) taken 4 times.
✓ Branch 2 (6→7) taken 4 times.
|
4 | defaultMode.getValue(configurationFile, "daemonconfig"); |
| 33 |
1/1✓ Branch 0 (8→9) taken 4 times.
|
4 | PString daemonName; |
| 34 |
2/2✓ Branch 0 (9→10) taken 4 times.
✓ Branch 2 (10→11) taken 4 times.
|
4 | defaultMode.getValue(daemonName, "daemonname"); |
| 35 |
2/2✓ Branch 0 (12→13) taken 4 times.
✓ Branch 2 (13→14) taken 4 times.
|
4 | p_isFullMock = defaultMode.isOptionExist("mock"); |
| 36 |
2/2✓ Branch 0 (15→16) taken 4 times.
✓ Branch 2 (16→17) taken 4 times.
|
4 | p_isFullMockRecord = defaultMode.isOptionExist("mockrecord"); |
| 37 |
1/1✓ Branch 0 (18→19) taken 4 times.
|
8 | return load(configurationFile, daemonName); |
| 38 | 4 | } | |
| 39 | |||
| 40 | ///Load configuration form a node of ConfigNode | ||
| 41 | /** @param[out] dico : loaded configuration | ||
| 42 | * @param daemonName : name of the current Daemon in the configuration | ||
| 43 | * @return true on success, false otherwise | ||
| 44 | */ | ||
| 45 | 31 | void BaseDaemon::loadConfigFromNode(const ConfigNode & dico, const PString & daemonName) { | |
| 46 |
2/2✓ Branch 0 (2→3) taken 31 times.
✓ Branch 2 (3→4) taken 31 times.
|
31 | const ConfigNode * mapMainConfig = dico.getChild("swarm"); |
| 47 |
2/2✓ Branch 0 (5→6) taken 14 times.
✓ Branch 1 (5→27) taken 17 times.
|
31 | if(mapMainConfig != nullptr){ |
| 48 |
2/2✓ Branch 0 (6→7) taken 14 times.
✓ Branch 2 (7→8) taken 14 times.
|
14 | p_mainConfig.recvTimeoutMs = phoenix_get_value<int>(*mapMainConfig, "recv_timeout_ms", -1); |
| 49 |
2/2✓ Branch 0 (9→10) taken 14 times.
✓ Branch 2 (10→11) taken 14 times.
|
14 | p_mainConfig.sendTimeoutMs = phoenix_get_value<int>(*mapMainConfig, "send_timeout_ms", -1); |
| 50 |
4/4✓ Branch 0 (12→13) taken 14 times.
✓ Branch 2 (13→14) taken 14 times.
✓ Branch 4 (14→15) taken 14 times.
✓ Branch 6 (15→16) taken 14 times.
|
14 | p_mainConfig.recvFlag = daemonRecvFlagFromString(phoenix_get_string(*mapMainConfig, "recv_flag", "NON_BLOCK")); |
| 51 |
4/4✓ Branch 0 (19→20) taken 14 times.
✓ Branch 2 (20→21) taken 14 times.
✓ Branch 4 (21→22) taken 14 times.
✓ Branch 6 (22→23) taken 14 times.
|
14 | p_mainConfig.sendFlag = daemonSendFlagFromString(phoenix_get_string(*mapMainConfig, "send_flag", "NON_BLOCK")); |
| 52 | } | ||
| 53 | 31 | std::map<PString, time_t> mapTimeout; | |
| 54 | 31 | const ConfigNode * extraConfigParam = nullptr; | |
| 55 |
1/1✓ Branch 0 (28→29) taken 19 times.
|
31 | daemon_read_configNode(p_config, p_mapDaemon, p_log, mapTimeout, extraConfigParam, dico, daemonName); |
| 56 | |||
| 57 |
2/2✓ Branch 0 (29→30) taken 19 times.
✓ Branch 2 (30→31) taken 19 times.
|
19 | const ConfigNode * mapStatDaemon = dico.getChild("statistics"); |
| 58 |
2/2✓ Branch 0 (32→33) taken 4 times.
✓ Branch 1 (32→39) taken 15 times.
|
19 | if(mapStatDaemon != nullptr){ |
| 59 |
3/3✓ Branch 0 (33→34) taken 4 times.
✓ Branch 2 (34→35) taken 4 times.
✓ Branch 4 (35→36) taken 4 times.
|
4 | p_config.setStatDaemonName(daemon_loadString(*mapStatDaemon, "stat_daemon_name")); |
| 60 | } | ||
| 61 |
1/1✓ Branch 0 (39→40) taken 19 times.
|
19 | p_config.setMapTimeout(mapTimeout); |
| 62 |
4/4✓ Branch 0 (40→41) taken 19 times.
✓ Branch 2 (41→42) taken 19 times.
✓ Branch 4 (42→43) taken 4 times.
✓ Branch 5 (42→52) taken 15 times.
|
19 | if(p_config.getStatDaemonName() != ""){ |
| 63 |
3/4✓ Branch 0 (43→44) taken 4 times.
✓ Branch 2 (44→45) taken 4 times.
✗ Branch 4 (45→46) not taken.
✓ Branch 5 (45→52) taken 4 times.
|
4 | if(!isDaemonExist(p_config.getStatDaemonName())){ |
| 64 | ✗ | p_log.getLogError() << "BaseDaemon::loadConfigFromNode : stat daemon '"<<p_config.getStatDaemonName()<<"' not found in configuration" << std::endl; | |
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 |
3/3✓ Branch 0 (52→53) taken 19 times.
✓ Branch 2 (53→54) taken 19 times.
✓ Branch 4 (54→55) taken 19 times.
|
19 | p_log.getLogInfo() << "BaseDaemon::loadConfigFromNode : loading configuration successful" << std::endl; |
| 69 |
3/3✓ Branch 0 (55→56) taken 19 times.
✓ Branch 2 (56→57) taken 19 times.
✓ Branch 4 (57→58) taken 19 times.
|
19 | p_log.getLogInfo() << "BaseDaemon::loadConfigFromNode : ready to call addCallMethod to subscribe on received data" << std::endl; |
| 70 |
1/1✓ Branch 0 (58→59) taken 19 times.
|
19 | addCallMethod(); |
| 71 | 31 | } | |
| 72 | |||
| 73 | ///Load the Json configuration which define all BaseDaemons of the Swarm | ||
| 74 | /** @param configFileContent : name of the configuration file of all the BaseDaemons of the Swarm in json format | ||
| 75 | * @param daemonName : name of the current BaseDaemon in the given file | ||
| 76 | * @param format : format of the configuration file | ||
| 77 | * @return true on success, false otherwise | ||
| 78 | */ | ||
| 79 | 9 | bool BaseDaemon::load(const PString & configFileContent, const PString & daemonName, ConfigFormat::ConfigFormat format){ | |
| 80 |
1/1✓ Branch 0 (2→3) taken 9 times.
|
9 | ConfigNode dico; |
| 81 |
1/1✓ Branch 0 (3→4) taken 9 times.
|
9 | daemon_load_config(p_log, dico, configFileContent, format); |
| 82 |
1/1✓ Branch 0 (4→5) taken 3 times.
|
9 | loadConfigFromNode(dico, daemonName); |
| 83 | 3 | return true; | |
| 84 | 9 | } | |
| 85 | |||
| 86 | ///Load the Toml configuration which define all BaseDaemons of the Swarm | ||
| 87 | /** @param fileName : name of the configuration file of all the BaseDaemons of the Swarm in toml format | ||
| 88 | * @param daemonName : name of the current BaseDaemon in the given file | ||
| 89 | * @return true on success, false otherwise | ||
| 90 | */ | ||
| 91 | 27 | bool BaseDaemon::load(const PPath & fileName, const PString & daemonName){ | |
| 92 |
1/1✓ Branch 0 (2→3) taken 27 times.
|
27 | ConfigNode dico; |
| 93 |
1/1✓ Branch 0 (3→4) taken 22 times.
|
27 | daemon_load_config(p_log, dico, fileName); |
| 94 |
1/1✓ Branch 0 (4→5) taken 16 times.
|
22 | loadConfigFromNode(dico, daemonName); |
| 95 | 16 | return true; | |
| 96 | 27 | } | |
| 97 | |||
| 98 | ///Extra call on load for the current Daemon | ||
| 99 | /** @param config : configuration for the current Daemon | ||
| 100 | * @return true on success, false otherwise | ||
| 101 | */ | ||
| 102 | ✗ | bool BaseDaemon::extraLoad(const ConfigNode * config){ | |
| 103 | ✗ | return true; | |
| 104 | } | ||
| 105 | |||
| 106 | ///Do the addCallableMethod here | ||
| 107 | 16 | void BaseDaemon::addCallMethod(){ | |
| 108 |
1/2✓ Branch 0 (3→4) taken 16 times.
✗ Branch 1 (3→7) not taken.
|
16 | if(p_log.isOpen()){ |
| 109 | 16 | p_log.getLogWarning() << "BaseDaemon::addCallMethod : no redefined addCallMethod " << std::endl; | |
| 110 | }else{ | ||
| 111 | ✗ | std::cerr << "BaseDaemon::addCallMethod : no redefined addCallMethod (and no log file so we use std::cerr)" << std::endl; | |
| 112 | } | ||
| 113 | 16 | } | |
| 114 | |||
| 115 | ///Call an added callable method by name | ||
| 116 | /** @param[out] result : result of the call | ||
| 117 | * @param name : name of the method | ||
| 118 | * @param parameter : parameters of the call | ||
| 119 | * @return true on success, false otherwise | ||
| 120 | */ | ||
| 121 | 2 | bool BaseDaemon::callMethod(Data & result, const PString & name, const Data & parameter){ | |
| 122 |
1/1✓ Branch 0 (2→3) taken 2 times.
|
2 | std::map<PString, AbstractFunction*>::iterator it(p_mapCallableMethod.find(name)); |
| 123 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→13) taken 2 times.
|
2 | if(it == p_mapCallableMethod.end()){ |
| 124 | ✗ | getLog().getLogError() << "BaseDaemon::callMethod : function '"<<name<<"' not found" << std::endl; | |
| 125 | ✗ | return false; | |
| 126 | } | ||
| 127 |
2/2✓ Branch 0 (13→14) taken 2 times.
✓ Branch 2 (14→15) taken 2 times.
|
2 | return p_mapCallableMethod[name]->call(p_log, result, parameter); |
| 128 | } | ||
| 129 | |||
| 130 | ///Clear the map of callable methods | ||
| 131 | 46 | void BaseDaemon::clearCallableMethod(){ | |
| 132 |
2/2✓ Branch 0 (9→3) taken 2 times.
✓ Branch 1 (9→10) taken 46 times.
|
48 | for(std::map<PString, AbstractFunction*>::iterator it(p_mapCallableMethod.begin()); it != p_mapCallableMethod.end(); ++it){ |
| 133 |
1/2✓ Branch 0 (4→5) taken 2 times.
✗ Branch 1 (4→6) not taken.
|
2 | delete it->second; |
| 134 | } | ||
| 135 | 46 | p_mapCallableMethod.clear(); | |
| 136 | 46 | } | |
| 137 | |||
| 138 | ///Stops the BaseDaemon | ||
| 139 | 9 | void BaseDaemon::stop(){ | |
| 140 | 9 | p_log.getLogInfo() << "Stopping Daemon '"<<p_config.getName()<<"' at '"<<p_config.getHostName()<<"'" << std::endl; | |
| 141 | 9 | p_isRun = false; | |
| 142 | 9 | } | |
| 143 | |||
| 144 | ///Return the OptionParser of the current BaseDaemon | ||
| 145 | /** @return OptionParser of the current BaseDaemon | ||
| 146 | */ | ||
| 147 | ✗ | OptionParser & BaseDaemon::getOptionParser(){ | |
| 148 | ✗ | return p_optionParser; | |
| 149 | } | ||
| 150 | |||
| 151 | ///Get the log of the current BaseDaemon | ||
| 152 | /** @return log of the current BaseDaemon | ||
| 153 | */ | ||
| 154 | 144 | PLog & BaseDaemon::getLog(){ | |
| 155 | 144 | return p_log; | |
| 156 | } | ||
| 157 | |||
| 158 | ///Say if a neighbour Daemon does exist | ||
| 159 | /** @param name : name of the Daemon to be searched | ||
| 160 | * @return true if the Daemon does exist, false otherwise | ||
| 161 | */ | ||
| 162 | 11 | bool BaseDaemon::isDaemonExist(const PString & name) const{ | |
| 163 |
1/1✓ Branch 0 (2→3) taken 11 times.
|
11 | MapDaemonConfig::const_iterator it(p_mapDaemon.find(name)); |
| 164 |
2/2✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→10) taken 10 times.
|
11 | if(it == p_mapDaemon.end()){ |
| 165 | //Then if the stat daemon does not exist in the map, it may be the current daemon | ||
| 166 |
2/3✓ Branch 0 (6→7) taken 1 times.
✓ Branch 2 (8→9) taken 1 times.
✗ Branch 3 (8→10) not taken.
|
1 | if(p_config.getName() == name){ |
| 167 | 1 | return true; | |
| 168 | } | ||
| 169 | } | ||
| 170 |
1/2✓ Branch 0 (12→13) taken 10 times.
✗ Branch 1 (12→14) not taken.
|
10 | if(it != p_mapDaemon.end()){ |
| 171 | 10 | return true; | |
| 172 | } | ||
| 173 | |||
| 174 | ✗ | return false; | |
| 175 | } | ||
| 176 | |||
| 177 | ///Add a message to confirm | ||
| 178 | /** @param message : message to be added | ||
| 179 | */ | ||
| 180 | 12 | void BaseDaemon::addMessageToConfirm(const Message & message){ | |
| 181 |
3/3✓ Branch 0 (2→3) taken 12 times.
✓ Branch 2 (3→4) taken 12 times.
✓ Branch 4 (4→5) taken 12 times.
|
12 | p_mapMessageToBeConfirmed[message.getId()] = message; |
| 182 | 12 | } | |
| 183 | |||
| 184 | ///Get a message to confirm by id if it exists | ||
| 185 | /** @param[out] message : message which has the id id | ||
| 186 | * @param id : id of the message to be searched | ||
| 187 | * @return true if the message with id id does exist, false otherwise | ||
| 188 | */ | ||
| 189 | 3 | bool BaseDaemon::getMessageToConfirm(Message & message, size_t id) const{ | |
| 190 |
1/1✓ Branch 0 (2→3) taken 3 times.
|
3 | std::map<size_t, Message>::const_iterator it(p_mapMessageToBeConfirmed.find(id)); |
| 191 |
2/2✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→9) taken 2 times.
|
3 | if(it != p_mapMessageToBeConfirmed.end()){ |
| 192 |
1/1✓ Branch 0 (7→8) taken 1 times.
|
1 | message = it->second; |
| 193 | 1 | return true; | |
| 194 | } | ||
| 195 | 2 | return false; | |
| 196 | } | ||
| 197 | |||
| 198 | ///Process confirmed message | ||
| 199 | /** @param id : id of the message to be removed | ||
| 200 | * @param currentTime : time when the confirmation was received | ||
| 201 | */ | ||
| 202 | 8 | void BaseDaemon::processConfirmedMessage(size_t id, time_t currentTime){ | |
| 203 |
1/1✓ Branch 0 (2→3) taken 8 times.
|
8 | std::map<size_t, Message>::const_iterator it(p_mapMessageToBeConfirmed.find(id)); |
| 204 |
1/2✓ Branch 0 (7→8) taken 8 times.
✗ Branch 1 (7→47) not taken.
|
8 | if(it != p_mapMessageToBeConfirmed.end()){ |
| 205 |
5/5✓ Branch 0 (8→9) taken 8 times.
✓ Branch 2 (9→10) taken 8 times.
✓ Branch 4 (10→11) taken 8 times.
✓ Branch 6 (11→12) taken 8 times.
✓ Branch 8 (12→13) taken 8 times.
|
8 | getLog().getLogInfo() << "BaseDaemon::processConfirmedMessage : adding statistics for processed transaction " << id << std::endl; |
| 206 | 8 | const Message & message = it->second; | |
| 207 |
1/1✓ Branch 0 (14→15) taken 8 times.
|
8 | time_t ellapsedTime = currentTime - message.getSendTime(); |
| 208 |
3/3✓ Branch 0 (15→16) taken 8 times.
✓ Branch 2 (40→18) taken 8 times.
✓ Branch 3 (40→41) taken 8 times.
|
24 | for(const PString & receiver : message.getVecRecver()){ |
| 209 |
5/5✓ Branch 0 (20→21) taken 8 times.
✓ Branch 2 (21→22) taken 8 times.
✓ Branch 4 (22→23) taken 8 times.
✓ Branch 6 (23→24) taken 8 times.
✓ Branch 8 (24→25) taken 8 times.
|
8 | getLog().getLogDebug() << "BaseDaemon::processConfirmedMessage : add statistic for receiver : " << receiver << std::endl; |
| 210 |
6/6✓ Branch 0 (25→26) taken 8 times.
✓ Branch 2 (26→27) taken 8 times.
✓ Branch 4 (27→28) taken 8 times.
✓ Branch 6 (28→29) taken 8 times.
✓ Branch 8 (29→30) taken 8 times.
✓ Branch 10 (30→31) taken 8 times.
|
8 | getCommunicationStat(receiver, message.getData().getType(), ellapsedTime, p_config.getStatNbBin(), p_config.getStatHistLowerBound(), p_config.getStatHistUpperBound()); |
| 211 | } | ||
| 212 | // Remove the confirmed message | ||
| 213 |
5/5✓ Branch 0 (41→42) taken 8 times.
✓ Branch 2 (42→43) taken 8 times.
✓ Branch 4 (43→44) taken 8 times.
✓ Branch 6 (44→45) taken 8 times.
✓ Branch 8 (45→46) taken 8 times.
|
8 | getLog().getLogInfo() << "BaseDaemon::removeConfirmedMessage : remove confirmed transaction " << id << std::endl; |
| 214 |
1/1✓ Branch 0 (46→53) taken 8 times.
|
8 | p_mapMessageToBeConfirmed.erase(it); |
| 215 | }else{ | ||
| 216 | ✗ | getLog().getLogError() << "BaseDaemon::processConfirmedMessage : transaction " << id << " not found in p_mapMessageToBeConfirmed" << std::endl; | |
| 217 | } | ||
| 218 | 8 | } | |
| 219 | |||
| 220 | /// Check if a message has reached the timeout | ||
| 221 | /** @param currentTime : current time | ||
| 222 | */ | ||
| 223 | 298 | void BaseDaemon::checkMessageTimeout(time_t currentTime){ | |
| 224 | 298 | std::vector<size_t> messagesToRemove; | |
| 225 |
2/2✓ Branch 0 (74→4) taken 569 times.
✓ Branch 1 (74→75) taken 298 times.
|
867 | for(auto it = p_mapMessageToBeConfirmed.begin(); it != p_mapMessageToBeConfirmed.end(); ++it){ |
| 226 | 569 | const size_t & messageId = it->first; | |
| 227 | 569 | const Message & message = it->second; | |
| 228 |
1/1✓ Branch 0 (6→7) taken 569 times.
|
569 | time_t elapsedTime = currentTime - message.getSendTime(); |
| 229 |
2/3✓ Branch 0 (7→8) taken 569 times.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→17) taken 569 times.
|
569 | if(message.getVecRecver().size() == 0lu){ |
| 230 | ✗ | getLog().getLogError() << "BaseDaemon::checkMessageTimeout() : message " << messageId << " has no receiver." << std::endl; | |
| 231 | ✗ | continue; | |
| 232 | } | ||
| 233 |
3/3✓ Branch 0 (17→18) taken 569 times.
✓ Branch 2 (18→19) taken 569 times.
✓ Branch 4 (20→21) taken 569 times.
|
569 | std::map<PString, time_t>::const_iterator timeoutIt = p_config.getMapTimeout().find(message.getVecRecver().front()); |
| 234 |
2/3✓ Branch 0 (22→23) taken 569 times.
✗ Branch 2 (26→27) not taken.
✓ Branch 3 (26→38) taken 569 times.
|
569 | if(timeoutIt == p_config.getMapTimeout().end()){ |
| 235 | ✗ | getLog().getLogError() << "BaseDaemon::checkMessageTimeout() : no timeout found for receiver '" << message.getVecRecver().front() << "' of message " << messageId << "." << std::endl; | |
| 236 | ✗ | continue; | |
| 237 | } | ||
| 238 | 569 | time_t timeout = timeoutIt->second; | |
| 239 |
5/5✓ Branch 0 (41→42) taken 569 times.
✓ Branch 2 (44→45) taken 569 times.
✓ Branch 4 (47→48) taken 569 times.
✓ Branch 6 (48→49) taken 569 times.
✓ Branch 8 (50→51) taken 569 times.
|
2845 | phoenix_assert(message.getVecRecver().size() != 0lu); |
| 240 |
2/2✓ Branch 0 (57→58) taken 1 times.
✓ Branch 1 (57→69) taken 568 times.
|
569 | if (elapsedTime > timeout) { |
| 241 |
1/1✓ Branch 0 (58→59) taken 1 times.
|
1 | messagesToRemove.push_back(messageId); |
| 242 |
9/9✓ Branch 0 (59→60) taken 1 times.
✓ Branch 2 (60→61) taken 1 times.
✓ Branch 4 (61→62) taken 1 times.
✓ Branch 6 (62→63) taken 1 times.
✓ Branch 8 (63→64) taken 1 times.
✓ Branch 10 (64→65) taken 1 times.
✓ Branch 12 (66→67) taken 1 times.
✓ Branch 14 (67→68) taken 1 times.
✓ Branch 16 (68→69) taken 1 times.
|
1 | getLog().getLogWarning() << "BaseDaemon::checkMessageTimeout() : Timeout Reached for message " << messageId << " sent to '" << message.getVecRecver().front() << "'. Removing unconfirmed transaction" << std::endl; |
| 243 | } | ||
| 244 | } | ||
| 245 |
2/2✓ Branch 0 (89→77) taken 1 times.
✓ Branch 1 (89→90) taken 298 times.
|
597 | for(const size_t & messageId : messagesToRemove){ |
| 246 |
1/1✓ Branch 0 (79→80) taken 1 times.
|
1 | p_mapMessageToBeConfirmed.erase(messageId); |
| 247 | } | ||
| 248 | 298 | } | |
| 249 | |||
| 250 | ///Get current message id | ||
| 251 | /** @return current message id | ||
| 252 | */ | ||
| 253 | 10 | size_t BaseDaemon::getMessageId(){ | |
| 254 | 10 | ++p_messageId; | |
| 255 | 10 | return p_messageId; | |
| 256 | } | ||
| 257 | |||
| 258 | ///Get the data function associated with the given data | ||
| 259 | /** @param data The data for which to retrieve the associated function | ||
| 260 | * @return A pointer to the associated data function, or nullptr if not found | ||
| 261 | */ | ||
| 262 | 14 | AbstractDataFunction* BaseDaemon::getDataFunction(const Data & data){ | |
| 263 |
2/2✓ Branch 0 (2→3) taken 14 times.
✓ Branch 2 (3→4) taken 14 times.
|
14 | PString prototype(data.getType()); |
| 264 |
1/1✓ Branch 0 (4→5) taken 14 times.
|
14 | std::map<PString, AbstractDataFunction*>::iterator it(p_mapDataFunction.find(prototype)); |
| 265 |
1/2✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→15) taken 14 times.
|
14 | if(it == p_mapDataFunction.end()){ |
| 266 | ✗ | getLog().getLogError() << "BaseDaemon::getDataFunction : function to process data '"<<prototype<<"' not found" << std::endl; | |
| 267 | ✗ | return nullptr; | |
| 268 | } | ||
| 269 | 14 | return it->second; | |
| 270 | 14 | } | |
| 271 | |||
| 272 | ///Process given data with the proper method | ||
| 273 | /** @param data : data to be processed | ||
| 274 | * @return true on success, false otherwise | ||
| 275 | */ | ||
| 276 | 5 | bool BaseDaemon::processData(const Data & data){ | |
| 277 | 5 | AbstractDataFunction* function = getDataFunction(data); | |
| 278 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 5 times.
|
5 | if(function == nullptr){ |
| 279 | ✗ | return false; | |
| 280 | } | ||
| 281 | 5 | getLog().getLogDebug() << "BaseDaemon::processData : process data '"<<data.getType()<<"'" << std::endl; | |
| 282 | 5 | bool b = function->call(p_log, data); | |
| 283 | 5 | return b; | |
| 284 | } | ||
| 285 | |||
| 286 | ///Update a computing statistic with a new value | ||
| 287 | /** @param stat : statistic to be updated | ||
| 288 | * @param value : new value to be added to the statistic | ||
| 289 | */ | ||
| 290 | 17 | void BaseDaemon::updateStatAccumulator(StatAccumulator & stat, float value){ | |
| 291 | 17 | stat.setNbEvent(stat.getNbEvent() + 1lu); | |
| 292 | 17 | getLog().getLogDebug() << "BaseDaemon::updateStatAccumulator : event nb is " << stat.getNbEvent() << std::endl; | |
| 293 |
2/2✓ Branch 0 (11→12) taken 6 times.
✓ Branch 1 (11→15) taken 11 times.
|
17 | if(stat.getNbEvent() == 1lu){ |
| 294 | 6 | stat.setMin(value); | |
| 295 | 6 | stat.setMax(value); | |
| 296 | 6 | stat.setSum(value); | |
| 297 | }else{ | ||
| 298 |
2/2✓ Branch 0 (16→17) taken 7 times.
✓ Branch 1 (16→18) taken 4 times.
|
11 | if(value < stat.getMin()){ |
| 299 | 7 | stat.setMin(value); | |
| 300 | } | ||
| 301 |
2/2✓ Branch 0 (19→20) taken 2 times.
✓ Branch 1 (19→21) taken 9 times.
|
11 | if(value > stat.getMax()){ |
| 302 | 2 | stat.setMax(value); | |
| 303 | } | ||
| 304 | 11 | stat.setSum(stat.getSum() + value); | |
| 305 | } | ||
| 306 |
2/2✓ Branch 0 (24→25) taken 8 times.
✓ Branch 1 (24→27) taken 9 times.
|
17 | if(value > stat.getHistUpperBound()){ |
| 307 | 8 | stat.setNbEventAboveUpperBound(stat.getNbEventAboveUpperBound() + 1lu); | |
| 308 | } | ||
| 309 |
2/2✓ Branch 0 (28→29) taken 1 times.
✓ Branch 1 (28→31) taken 16 times.
|
17 | if(value < stat.getHistLowerBound()){ |
| 310 | 1 | stat.setNbEventBelowLowerBound(stat.getNbEventBelowLowerBound() + 1lu); | |
| 311 | } | ||
| 312 | 17 | float binSize = (stat.getHistUpperBound() - stat.getHistLowerBound()) / stat.getVecHistogram().size(); | |
| 313 | 17 | size_t bin = (value - stat.getHistLowerBound()) / binSize; | |
| 314 |
2/2✓ Branch 0 (38→39) taken 9 times.
✓ Branch 1 (38→43) taken 8 times.
|
17 | if(bin < stat.getVecHistogram().size()){ |
| 315 | 9 | std::vector<size_t> & vecHistogram = stat.getVecHistogram(); | |
| 316 | 9 | vecHistogram[bin] = vecHistogram[bin] + 1lu; | |
| 317 | } | ||
| 318 | 17 | } | |
| 319 | |||
| 320 | ///Create a new clear computing statistic | ||
| 321 | /** @param nbBin : number of bin of the histogram | ||
| 322 | * @param histLowerBound : lower bound of the histogram | ||
| 323 | * @param histUpperBound : upper bound of the histogram | ||
| 324 | * @return new clear computing statistic | ||
| 325 | */ | ||
| 326 | 13 | StatAccumulator BaseDaemon::createNewStat(size_t nbBin, float histLowerBound, float histUpperBound){ | |
| 327 | 13 | StatAccumulator newStat; | |
| 328 |
1/1✓ Branch 0 (3→4) taken 13 times.
|
13 | newStat.setNbEvent(0lu); |
| 329 |
1/1✓ Branch 0 (4→5) taken 13 times.
|
13 | newStat.setMin(std::nan("")); |
| 330 |
1/1✓ Branch 0 (5→6) taken 13 times.
|
13 | newStat.setMax(std::nan("")); |
| 331 |
1/1✓ Branch 0 (6→7) taken 13 times.
|
13 | newStat.setSum(std::nan("")); |
| 332 |
1/1✓ Branch 0 (7→8) taken 13 times.
|
13 | newStat.setNbEventAboveUpperBound(0lu); |
| 333 |
1/1✓ Branch 0 (8→9) taken 13 times.
|
13 | newStat.setNbEventBelowLowerBound(0lu); |
| 334 |
1/1✓ Branch 0 (9→10) taken 13 times.
|
13 | newStat.setHistUpperBound(histUpperBound); |
| 335 |
1/1✓ Branch 0 (10→11) taken 13 times.
|
13 | newStat.setHistLowerBound(histLowerBound); |
| 336 |
2/2✓ Branch 0 (13→14) taken 13 times.
✓ Branch 2 (14→15) taken 13 times.
|
13 | newStat.setVecHistogram(std::vector<size_t>(nbBin, 0lu)); |
| 337 | 13 | return newStat; | |
| 338 | ✗ | } | |
| 339 | |||
| 340 | ///Get the map of message to be confirmed | ||
| 341 | /** @return map of message to be confirmed | ||
| 342 | */ | ||
| 343 | 140 | const std::map<size_t, Message> & BaseDaemon::getMapMessageToBeConfirmed() const { | |
| 344 | 140 | return p_mapMessageToBeConfirmed; | |
| 345 | } | ||
| 346 | |||
| 347 | |||
| 348 | ///Clear all the statistics of the daemon | ||
| 349 | 171 | void BaseDaemon::clearStat(){ | |
| 350 |
6/6✓ Branch 0 (2→3) taken 171 times.
✓ Branch 2 (3→4) taken 171 times.
✓ Branch 4 (21→22) taken 338 times.
✓ Branch 6 (22→23) taken 338 times.
✓ Branch 8 (25→5) taken 167 times.
✓ Branch 9 (25→26) taken 171 times.
|
338 | for(MapStatAccumulator::iterator it = p_config.getDaemonStatAccumulator().getMapStatComputing().begin(); it != p_config.getDaemonStatAccumulator().getMapStatComputing().end(); ++it){ |
| 351 |
1/1✓ Branch 0 (6→7) taken 167 times.
|
167 | it->second.setNbEvent(0lu); |
| 352 |
2/2✓ Branch 0 (8→9) taken 167 times.
✓ Branch 2 (11→12) taken 167 times.
|
334 | std::fill(it->second.getVecHistogram().begin(), it->second.getVecHistogram().end(), 0lu); |
| 353 | } | ||
| 354 |
6/6✓ Branch 0 (26→27) taken 171 times.
✓ Branch 2 (27→28) taken 171 times.
✓ Branch 4 (52→53) taken 173 times.
✓ Branch 6 (53→54) taken 173 times.
✓ Branch 8 (56→29) taken 2 times.
✓ Branch 9 (56→57) taken 171 times.
|
173 | for(MapDaemonStatAccumulator::iterator itMap = p_config.getDaemonStatAccumulator().getMapStatCommunication().begin(); itMap != p_config.getDaemonStatAccumulator().getMapStatCommunication().end(); ++itMap){ |
| 355 |
2/2✓ Branch 0 (50→31) taken 2 times.
✓ Branch 1 (50→51) taken 2 times.
|
4 | for(MapStatAccumulator::iterator it = itMap->second.begin(); it != itMap->second.end(); ++it){ |
| 356 |
1/1✓ Branch 0 (32→33) taken 2 times.
|
2 | it->second.setNbEvent(0lu); |
| 357 |
2/2✓ Branch 0 (34→35) taken 2 times.
✓ Branch 2 (37→38) taken 2 times.
|
4 | std::fill(it->second.getVecHistogram().begin(), it->second.getVecHistogram().end(), 0lu); |
| 358 | } | ||
| 359 | } | ||
| 360 | 171 | } | |
| 361 | |||
| 362 | ///Get the configuration of the current BaseDaemon | ||
| 363 | /** @return configuration of the current BaseDaemon | ||
| 364 | */ | ||
| 365 | 14 | DaemonConfig & BaseDaemon::getConfig(){ | |
| 366 | 14 | return p_config; | |
| 367 | } | ||
| 368 | |||
| 369 | ///Get the map of all Daemon configurations | ||
| 370 | /** @return map of all Daemon configurations | ||
| 371 | */ | ||
| 372 | 1 | MapDaemonConfig & BaseDaemon::getMapDaemonConfig(){ | |
| 373 | 1 | return p_mapDaemon; | |
| 374 | } | ||
| 375 | |||
| 376 | ///Get the main configuration of the swarm | ||
| 377 | /** @return main configuration of the swarm | ||
| 378 | */ | ||
| 379 | 1 | DaemonMainConfig & BaseDaemon::getMainConfig(){ | |
| 380 | 1 | return p_mainConfig; | |
| 381 | } | ||
| 382 | |||
| 383 | ///Get the logger of the current BaseDaemon | ||
| 384 | /** @return logger of the current BaseDaemon | ||
| 385 | */ | ||
| 386 | 1 | PLog & BaseDaemon::getLogger(){ | |
| 387 | 1 | return p_log; | |
| 388 | } | ||
| 389 | |||
| 390 | ///Initialisation function of the class BaseDaemon | ||
| 391 | 46 | void BaseDaemon::initialisationBaseDaemon(){ | |
| 392 |
2/2✓ Branch 0 (2→3) taken 46 times.
✓ Branch 2 (3→4) taken 46 times.
|
46 | p_optionParser.setExampleLongOption("phoenix_daemon --daemonconfig=daemon_config.toml --daemonname=main"); |
| 393 |
2/2✓ Branch 0 (5→6) taken 46 times.
✓ Branch 2 (6→7) taken 46 times.
|
46 | p_optionParser.setExampleShortOption("phoenix_daemon -c daemon_config.toml -n main"); |
| 394 |
4/4✓ Branch 0 (8→9) taken 46 times.
✓ Branch 2 (9→10) taken 46 times.
✓ Branch 4 (10→11) taken 46 times.
✓ Branch 6 (11→12) taken 46 times.
|
46 | p_optionParser.addOption("daemonconfig", "c", OptionType::FILENAME, true, "Toml configuration file which define all Daemons of the swarm"); |
| 395 |
4/4✓ Branch 0 (15→16) taken 46 times.
✓ Branch 2 (16→17) taken 46 times.
✓ Branch 4 (17→18) taken 46 times.
✓ Branch 6 (18→19) taken 46 times.
|
46 | p_optionParser.addOption("daemonname", "n", OptionType::STRING, true, "Name of the current Daemon of the swarm configuration defined with --daemonconfig"); |
| 396 |
4/4✓ Branch 0 (22→23) taken 46 times.
✓ Branch 2 (23→24) taken 46 times.
✓ Branch 4 (24→25) taken 46 times.
✓ Branch 6 (25→26) taken 46 times.
|
46 | p_optionParser.addOption("mock", "m", OptionType::NONE, false, "Activate the Daemon in mock mode for the sockets and the clock"); |
| 397 |
4/4✓ Branch 0 (29→30) taken 46 times.
✓ Branch 2 (30→31) taken 46 times.
✓ Branch 4 (31→32) taken 46 times.
✓ Branch 6 (32→33) taken 46 times.
|
46 | p_optionParser.addOption("mockrecord", "r", OptionType::NONE, false, "Activate the Daemon in mock record mode for the sockets and the clock"); |
| 398 | 46 | p_isRun = false; | |
| 399 | 46 | p_messageId = 0lu; | |
| 400 | 46 | p_isFullMock = false; | |
| 401 | 46 | p_isFullMockRecord = false; | |
| 402 | 46 | } | |
| 403 | |||
| 404 | ///Create a new map of communication statistic | ||
| 405 | /** @param dataType : type of data which where pushed | ||
| 406 | * @param nbBin : number of bin of the histogram | ||
| 407 | * @param histLowerBound : lower bound of the histogram | ||
| 408 | * @param histUpperBound : upper bound of the histogram | ||
| 409 | * @return new map of communication statistic | ||
| 410 | */ | ||
| 411 | 4 | std::map<PString, StatAccumulator> BaseDaemon::createNewCommunicationStatMap(const PString & dataType, size_t nbBin, float histLowerBound, float histUpperBound){ | |
| 412 | 4 | std::map<PString, StatAccumulator> newStatMap; | |
| 413 |
3/3✓ Branch 0 (3→4) taken 4 times.
✓ Branch 2 (4→5) taken 4 times.
✓ Branch 4 (5→6) taken 4 times.
|
4 | newStatMap[dataType] = createNewStat(nbBin, histLowerBound, histUpperBound); |
| 414 | 4 | return newStatMap; | |
| 415 | ✗ | } | |
| 416 | |||
| 417 | ///Add a communication statistic | ||
| 418 | /** @param destName : name of the destination Daemon from which data where pushed | ||
| 419 | * @param dataType : type of data which where pushed | ||
| 420 | * @param latency : latency between the send of the data and the receiving of the confirmation by the daemon destName | ||
| 421 | * @param nbBin : number of bin of the histogram | ||
| 422 | * @param histLowerBound : lower bound of the histogram | ||
| 423 | * @param histUpperBound : upper bound of the histogram | ||
| 424 | */ | ||
| 425 | 8 | void BaseDaemon::getCommunicationStat(const PString & destName, const PString & dataType, float latency, size_t nbBin, float histLowerBound, float histUpperBound){ | |
| 426 |
2/2✓ Branch 0 (2→3) taken 8 times.
✓ Branch 2 (3→4) taken 8 times.
|
8 | std::map<PString, std::map<PString, StatAccumulator> > & mapCommunication = p_config.getDaemonStatAccumulator().getMapStatCommunication(); |
| 427 |
1/1✓ Branch 0 (4→5) taken 8 times.
|
8 | MapDaemonStatAccumulator::iterator it = mapCommunication.find(destName); |
| 428 |
2/2✓ Branch 0 (7→8) taken 4 times.
✓ Branch 1 (7→13) taken 4 times.
|
8 | if(it == mapCommunication.end()){ |
| 429 |
2/2✓ Branch 0 (8→9) taken 4 times.
✓ Branch 2 (9→10) taken 4 times.
|
4 | mapCommunication[destName] = createNewCommunicationStatMap(dataType, nbBin, histLowerBound, histUpperBound); |
| 430 | } | ||
| 431 | else{ | ||
| 432 |
1/1✓ Branch 0 (14→15) taken 4 times.
|
4 | std::map<PString, StatAccumulator>::iterator itDataType = it->second.find(dataType); |
| 433 |
1/2✗ Branch 0 (18→19) not taken.
✓ Branch 1 (18→25) taken 4 times.
|
4 | if(itDataType == it->second.end()){ |
| 434 | ✗ | it->second[dataType] = createNewStat(nbBin, histLowerBound, histUpperBound); | |
| 435 | } | ||
| 436 | } | ||
| 437 |
5/5✓ Branch 0 (26→27) taken 8 times.
✓ Branch 2 (27→28) taken 8 times.
✓ Branch 4 (28→29) taken 8 times.
✓ Branch 6 (30→31) taken 8 times.
✓ Branch 8 (31→32) taken 8 times.
|
8 | updateStatAccumulator(p_config.getDaemonStatAccumulator().getMapStatCommunication().find(destName)->second[dataType], latency); |
| 438 | 8 | } | |
| 439 | |||
| 440 | ///Fill a VecStat from a StatAccumulator to send to the DamonStat | ||
| 441 | /** @param accumulator StatAccumulator to be converted | ||
| 442 | * @param startTimestamp time at which the statistic started to be filled | ||
| 443 | * @param endTimestamp time at which the statistic stopped to be filled | ||
| 444 | * @return VecStat filled with the statistics from the accumulator | ||
| 445 | */ | ||
| 446 | 170 | VecStat BaseDaemon::fillVecStat(const StatAccumulator & accumulator, time_t startTimestamp, time_t endTimestamp){ | |
| 447 | 170 | VecStat vecStat; | |
| 448 | |||
| 449 | // Compute event values | ||
| 450 |
3/3✓ Branch 0 (3→4) taken 170 times.
✓ Branch 2 (4→5) taken 170 times.
✓ Branch 4 (5→6) taken 170 times.
|
170 | vecStat.getNbEvent().push_back(accumulator.getNbEvent()); |
| 451 |
3/3✓ Branch 0 (6→7) taken 170 times.
✓ Branch 2 (7→8) taken 170 times.
✓ Branch 4 (8→9) taken 170 times.
|
170 | vecStat.getMin().push_back(accumulator.getMin()); |
| 452 |
3/3✓ Branch 0 (9→10) taken 170 times.
✓ Branch 2 (10→11) taken 170 times.
✓ Branch 4 (11→12) taken 170 times.
|
170 | vecStat.getMax().push_back(accumulator.getMax()); |
| 453 |
4/4✓ Branch 0 (12→13) taken 170 times.
✓ Branch 2 (13→14) taken 170 times.
✓ Branch 4 (14→15) taken 170 times.
✓ Branch 6 (15→16) taken 170 times.
|
170 | vecStat.getAverage().push_back(accumulator.getSum() / accumulator.getNbEvent()); |
| 454 | |||
| 455 | // Compute time values | ||
| 456 |
2/2✓ Branch 0 (16→17) taken 170 times.
✓ Branch 2 (17→18) taken 170 times.
|
170 | vecStat.getStartTimestamp().push_back(startTimestamp); |
| 457 |
2/2✓ Branch 0 (18→19) taken 170 times.
✓ Branch 2 (19→20) taken 170 times.
|
170 | vecStat.getEndTimestamp().push_back(endTimestamp); |
| 458 | 170 | time_t rate = endTimestamp - startTimestamp; | |
| 459 |
3/3✓ Branch 0 (20→21) taken 170 times.
✓ Branch 2 (21→22) taken 170 times.
✓ Branch 4 (22→23) taken 170 times.
|
170 | vecStat.getRate().push_back(accumulator.getNbEvent()*1e9 / rate); |
| 460 |
3/3✓ Branch 0 (23→24) taken 170 times.
✓ Branch 2 (24→25) taken 170 times.
✓ Branch 4 (25→26) taken 170 times.
|
170 | vecStat.getRateEventAboveUpperBound().push_back(accumulator.getNbEventAboveUpperBound()*1e9 / rate); |
| 461 |
3/3✓ Branch 0 (26→27) taken 170 times.
✓ Branch 2 (27→28) taken 170 times.
✓ Branch 4 (28→29) taken 170 times.
|
170 | vecStat.getRateEventBelowLowerBound().push_back(accumulator.getNbEventBelowLowerBound()*1e9 / rate); |
| 462 | |||
| 463 |
3/3✓ Branch 0 (29→30) taken 170 times.
✓ Branch 2 (30→31) taken 170 times.
✓ Branch 4 (32→33) taken 170 times.
|
170 | vecStat.getVecRateQuantile().resize(accumulator.getVecHistogram().size()); |
| 464 |
3/3✓ Branch 0 (40→41) taken 8415 times.
✓ Branch 2 (42→34) taken 8245 times.
✓ Branch 3 (42→43) taken 170 times.
|
8415 | for(size_t i = 0; i < accumulator.getVecHistogram().size(); ++i){ |
| 465 |
3/3✓ Branch 0 (34→35) taken 8245 times.
✓ Branch 2 (36→37) taken 8245 times.
✓ Branch 4 (38→39) taken 8245 times.
|
8245 | vecStat.getVecRateQuantile()[i].push_back(accumulator.getVecHistogram()[i]*1e9 / rate); |
| 466 | } | ||
| 467 | 170 | return vecStat; | |
| 468 | ✗ | } | |
| 469 | |||
| 470 | /// @brief Fill the DaemonStat with the current statistics of the daemon | ||
| 471 | /** | ||
| 472 | * @param stat DaemonStat to be filled | ||
| 473 | * @param startTimestamp time at which the statistic started to be filled | ||
| 474 | * @param endTimestamp time at which the statistic stopped to be filled | ||
| 475 | */ | ||
| 476 | 171 | void BaseDaemon::fillDaemonStat(DaemonStat & stat, time_t startTimestamp, time_t endTimestamp){ | |
| 477 | // Fill the computing statistics | ||
| 478 | 171 | MapStatAccumulator & mapStatComputing = p_config.getDaemonStatAccumulator().getMapStatComputing(); | |
| 479 |
2/2✓ Branch 0 (15→5) taken 167 times.
✓ Branch 1 (15→16) taken 171 times.
|
338 | for(MapStatAccumulator::iterator it = mapStatComputing.begin(); it != mapStatComputing.end(); ++it){ |
| 480 | 167 | StatAccumulator & accumulator = it->second; | |
| 481 |
1/1✓ Branch 0 (6→7) taken 167 times.
|
167 | VecStat vecStat = fillVecStat(accumulator, startTimestamp, endTimestamp); |
| 482 |
3/3✓ Branch 0 (7→8) taken 167 times.
✓ Branch 2 (9→10) taken 167 times.
✓ Branch 4 (10→11) taken 167 times.
|
167 | stat.getMapStatComputing()[it->first] = vecStat; |
| 483 | 167 | } | |
| 484 | |||
| 485 | // Fill the communication statistics | ||
| 486 | 171 | MapDaemonStatAccumulator & mapStatCommunication = p_config.getDaemonStatAccumulator().getMapStatCommunication(); | |
| 487 |
2/2✓ Branch 0 (38→19) taken 2 times.
✓ Branch 1 (38→39) taken 171 times.
|
173 | for(MapDaemonStatAccumulator::iterator itMap = mapStatCommunication.begin(); itMap != mapStatCommunication.end(); ++itMap){ |
| 488 | 2 | const PString & destName = itMap->first; | |
| 489 |
2/2✓ Branch 0 (20→21) taken 2 times.
✓ Branch 2 (21→22) taken 2 times.
|
2 | std::map<PString, VecStat> & mapVecStat = stat.getMapStatCommunication()[destName]; |
| 490 |
2/2✓ Branch 0 (34→24) taken 2 times.
✓ Branch 1 (34→35) taken 2 times.
|
4 | for(MapStatAccumulator::iterator it = itMap->second.begin(); it != itMap->second.end(); ++it){ |
| 491 | 2 | StatAccumulator & accumulator = it->second; | |
| 492 |
1/1✓ Branch 0 (25→26) taken 2 times.
|
2 | VecStat vecStat = fillVecStat(accumulator, startTimestamp, endTimestamp); |
| 493 |
2/2✓ Branch 0 (27→28) taken 2 times.
✓ Branch 2 (28→29) taken 2 times.
|
2 | mapVecStat[it->first] = vecStat; |
| 494 | 2 | } | |
| 495 | } | ||
| 496 | 171 | } | |
| 497 | |||
| 498 |