|
24 | 24 | #include <string> |
25 | 25 | #include <map> |
26 | 26 | #include <cassert> |
| 27 | +#include <future> |
| 28 | + |
| 29 | +#include <boost/uuid/uuid.hpp> |
| 30 | +#include <boost/uuid/uuid_generators.hpp> |
| 31 | +#include <boost/uuid/uuid_io.hpp> |
| 32 | +#include <boost/lexical_cast.hpp> |
| 33 | +#include <boost/asio/ip/host_name.hpp> |
27 | 34 |
|
28 | 35 | namespace o2 |
29 | 36 | { |
@@ -52,13 +59,13 @@ struct ProcessType { |
52 | 59 | mType = -1; |
53 | 60 | } |
54 | 61 |
|
55 | | - constexpr operator int() const { return mType; } |
| 62 | + // constexpr operator int() const { return mType; } |
56 | 63 |
|
57 | 64 | constexpr bool operator==(const ProcessType &b) const { return mType == b.mType; } |
58 | 65 | constexpr bool operator!=(const ProcessType &b) const { return mType != b.mType; } |
59 | 66 | constexpr bool operator<(const ProcessType &b) const { return mType < b.mType; } |
60 | 67 |
|
61 | | - operator std::string() const { |
| 68 | + std::string to_string() const { |
62 | 69 |
|
63 | 70 | if (*this == ProcessType::StfBuilder) |
64 | 71 | return "StfBuilder"; |
@@ -165,20 +172,72 @@ class Config { |
165 | 172 | } |
166 | 173 |
|
167 | 174 | static |
168 | | - std::string getIdOption(const FairMQProgOptions& pFMQProgOpt) |
| 175 | + std::string getIdOption(const ProcessType pProcType, const FairMQProgOptions& pFMQProgOpt) |
169 | 176 | { |
170 | | - auto lId = pFMQProgOpt.GetValue<std::string>(OptionKeyDiscoveryId); |
171 | | - if (lId.empty()) { |
172 | | - DDLOG(fair::Severity::ERROR) << "Process must have unique ID for DataDistribution discovery."; |
173 | | - throw std::invalid_argument("Process ID for DataDiscovery must be provided."); |
| 177 | + // check cmdline first |
| 178 | + { |
| 179 | + std::string lId = pFMQProgOpt.GetValue<std::string>(OptionKeyDiscoveryId); |
| 180 | + if (!lId.empty()) { |
| 181 | + IDDLOG("Parameter <{}> provided on command line. value={}", OptionKeyDiscoveryId, lId); |
| 182 | + return lId; |
| 183 | + } |
| 184 | + |
| 185 | + if (pProcType == ProcessType::StfSender) { |
| 186 | + const auto lErrorMsg = fmt::format("Parameter <{}> for StfSender must be provided on command line.", |
| 187 | + OptionKeyDiscoveryId); |
| 188 | + EDDLOG( lErrorMsg); |
| 189 | + throw std::invalid_argument(lErrorMsg); |
| 190 | + } |
| 191 | + } |
| 192 | + |
| 193 | + { |
| 194 | + // get an unique ID |
| 195 | + std::string lUniquePart = boost::lexical_cast<std::string>(boost::uuids::random_generator()()); |
| 196 | + std::string lUniqueId = pProcType.to_string() + "-" + boost::asio::ip::host_name() + "-" + lUniquePart; |
| 197 | + |
| 198 | + IDDLOG("Parameter {} not provided, using random value={}", Config::OptionKeyDiscoveryId, lUniqueId); |
| 199 | + return lUniqueId; |
174 | 200 | } |
175 | | - return lId; |
176 | 201 | } |
177 | 202 |
|
178 | 203 | static |
179 | 204 | std::string getPartitionOption(const FairMQProgOptions& pFMQProgOpt) |
180 | 205 | { |
181 | | - return pFMQProgOpt.GetValue<std::string>(OptionKeyDiscoveryPartition); |
| 206 | + // check cmdline first |
| 207 | + { |
| 208 | + std::string lPartId = pFMQProgOpt.GetValue<std::string>(OptionKeyDiscoveryPartition); |
| 209 | + if (!lPartId.empty()) { |
| 210 | + IDDLOG("Parameter <{}> provided on command line. value={}", |
| 211 | + OptionKeyDiscoveryPartition, lPartId); |
| 212 | + return lPartId; |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + // setup for ODC |
| 217 | + std::promise<std::string> mPartIdPromise; |
| 218 | + std::future<std::string> mPartIdFuture = mPartIdPromise.get_future(); |
| 219 | + |
| 220 | + pFMQProgOpt.Subscribe<std::string>("o2.datadist", [&](const std::string& pKey, std::string pValue) { |
| 221 | + IDDLOG("Config::Subscribe received key-value pair <{}>=<{}>", pKey, pValue); |
| 222 | + |
| 223 | + // partition key for tf builder |
| 224 | + if (pKey == OptionKeyDiscoveryPartition) { |
| 225 | + mPartIdPromise.set_value(pValue); |
| 226 | + } else { |
| 227 | + EDDLOG("Config::Subscribe unrecognized key value pushed {}={}", pKey, pValue); |
| 228 | + } |
| 229 | + }); |
| 230 | + |
| 231 | + // wait for an ODC value |
| 232 | + mPartIdFuture.wait(); |
| 233 | + const auto lDiscId = mPartIdFuture.get(); |
| 234 | + if (lDiscId.length() == 0) { |
| 235 | + EDDLOG("Parameter {} provided from ODC. zero length", Config::OptionKeyDiscoveryPartition); |
| 236 | + throw std::invalid_argument(fmt::format("Invalid ODC parameter <{}>: zero length", Config::OptionKeyDiscoveryPartition)); |
| 237 | + } |
| 238 | + |
| 239 | + IDDLOG("Parameter {} provided from ODC. value={}", Config::OptionKeyDiscoveryPartition, lDiscId); |
| 240 | + return lDiscId; |
182 | 241 | } |
183 | 242 |
|
184 | 243 | Config() = delete; |
|
0 commit comments