10 #include "canvas/Utilities/Exception.h"
11 #include "cetlib/exception.h"
13 #include "artdaq-core/Data/Fragment.hh"
14 #include "artdaq-core/Utilities/ExceptionHandler.hh"
16 #include "artdaq/Application/RoutingMasterCore.hh"
17 #include "artdaq/DAQdata/Globals.hh"
18 #include "artdaq/Application/Routing/makeRoutingMasterPolicy.hh"
22 #define TRACE_NAME "RoutingMasterCore"
31 , received_token_counter_()
32 , shutdown_requested_(false)
33 , stop_requested_(false)
34 , pause_requested_(false)
39 TLOG_DEBUG(name_) <<
"Constructor" << TLOG_ENDL;
42 metricMan = &metricMan_;
48 TLOG_DEBUG(name_) <<
"Destructor" << TLOG_ENDL;
49 if (ev_token_receive_thread_.joinable()) ev_token_receive_thread_.join();
54 TLOG_DEBUG(name_) <<
"initialize method called with "
55 <<
"ParameterSet = \"" << pset.to_string()
56 <<
"\"." << TLOG_ENDL;
59 fhicl::ParameterSet daq_pset;
62 daq_pset = pset.get<fhicl::ParameterSet>(
"daq");
67 <<
"Unable to find the DAQ parameters in the initialization "
68 <<
"ParameterSet: \"" + pset.to_string() +
"\"." << TLOG_ENDL;
73 policy_pset_ = daq_pset.get<fhicl::ParameterSet>(
"policy");
78 <<
"Unable to find the policy parameters in the DAQ initialization ParameterSet: \"" + daq_pset.to_string() +
"\"." << TLOG_ENDL;
83 fhicl::ParameterSet metric_pset;
86 metric_pset = daq_pset.get<fhicl::ParameterSet>(
"metrics");
90 if (metric_pset.is_empty())
92 TLOG_INFO(name_) <<
"No metric plugins appear to be defined" << TLOG_ENDL;
96 metricMan_.initialize(metric_pset, name_);
100 ExceptionHandler(ExceptionHandlerRethrow::no,
101 "Error loading metrics in RoutingMasterCore::initialize()");
105 auto policy_plugin_spec = policy_pset_.get<std::string>(
"policy",
"");
106 if (policy_plugin_spec.length() == 0)
109 <<
"No fragment generator (parameter name = \"policy\") was "
110 <<
"specified in the policy ParameterSet. The "
111 <<
"DAQ initialization PSet was \"" << daq_pset.to_string() <<
"\"." << TLOG_ENDL;
120 std::stringstream exception_string;
121 exception_string <<
"Exception thrown during initialization of policy of type \""
122 << policy_plugin_spec <<
"\"";
124 ExceptionHandler(ExceptionHandlerRethrow::no, exception_string.str());
126 TLOG_DEBUG(name_) <<
"FHiCL parameter set used to initialize the policy which threw an exception: " << policy_pset_.to_string() << TLOG_ENDL;
131 rt_priority_ = daq_pset.get<
int>(
"rt_priority", 0);
132 sender_ranks_ = daq_pset.get<std::vector<int>>(
"sender_ranks");
133 num_receivers_ = policy_->GetReceiverCount();
135 receive_ack_events_ = std::vector<epoll_event>(sender_ranks_.size());
136 receive_token_events_ = std::vector<epoll_event>(num_receivers_);
138 auto mode = daq_pset.get<
bool>(
"senders_send_by_send_count",
false);
139 routing_mode_ = mode ? detail::RoutingMasterMode::RouteBySendCount : detail::RoutingMasterMode::RouteBySequenceID;
140 max_table_update_interval_ms_ = daq_pset.get<
size_t>(
"table_update_interval_ms", 1000);
141 current_table_interval_ms_ = max_table_update_interval_ms_;
142 max_ack_cycle_count_ = daq_pset.get<
size_t>(
"table_ack_retry_count", 5);
143 receive_token_port_ = daq_pset.get<
int>(
"routing_token_port", 35555);
144 send_tables_port_ = daq_pset.get<
int>(
"table_update_port", 35556);
145 receive_acks_port_ = daq_pset.get<
int>(
"table_acknowledge_port", 35557);
146 send_tables_address_ = daq_pset.get<std::string>(
"table_update_address",
"227.128.12.28");
147 receive_address_ = daq_pset.get<std::string>(
"routing_master_hostname",
"localhost");
150 statsHelper_.createCollectors(daq_pset, 100, 30.0, 60.0, TABLE_UPDATES_STAT_KEY);
152 shutdown_requested_.store(
false);
153 start_recieve_token_thread_();
159 stop_requested_.store(
false);
160 pause_requested_.store(
false);
162 statsHelper_.resetStatistics();
165 metricMan_.do_start();
167 table_update_count_ = 0;
168 received_token_count_ = 0;
170 TLOG_DEBUG(name_) <<
"Started run " << std::to_string(run_id_.run()) << TLOG_ENDL;
176 TLOG_DEBUG(name_) <<
"Stopping run " << std::to_string(run_id_.run())
177 <<
" after " << std::to_string(table_update_count_) <<
" table updates."
178 <<
" and " << received_token_count_ <<
" received tokens." << TLOG_ENDL;
179 stop_requested_.store(
true);
185 TLOG_DEBUG(name_) <<
"Pausing run " << std::to_string(run_id_.run())
186 <<
" after " << table_update_count_ <<
" table updates."
187 <<
" and " << received_token_count_ <<
" received tokens." << TLOG_ENDL;
188 pause_requested_.store(
true);
194 TLOG_DEBUG(name_) <<
"Resuming run " << run_id_.run() << TLOG_ENDL;
196 pause_requested_.store(
false);
197 metricMan_.do_start();
203 policy_.reset(
nullptr);
204 metricMan_.shutdown();
205 shutdown_requested_.store(
true);
211 TLOG_DEBUG(name_) <<
"soft_initialize method called with "
212 <<
"ParameterSet = \"" << pset.to_string()
213 <<
"\"." << TLOG_ENDL;
214 return initialize(pset, e, f);
219 TLOG_DEBUG(name_) <<
"reinitialize method called with "
220 <<
"ParameterSet = \"" << pset.to_string()
221 <<
"\"." << TLOG_ENDL;
222 return initialize(pset, e, f);
227 if (rt_priority_ > 0)
229 #pragma GCC diagnostic push
230 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
231 sched_param s_param = {};
232 s_param.sched_priority = rt_priority_;
233 if (pthread_setschedparam(pthread_self(), SCHED_RR, &s_param))
234 TLOG_WARNING(name_) <<
"setting realtime priority failed" << TLOG_ENDL;
235 #pragma GCC diagnostic pop
241 if (rt_priority_ > 0)
243 #pragma GCC diagnostic push
244 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
245 sched_param s_param = {};
246 s_param.sched_priority = rt_priority_;
247 int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
251 <<
"Failed to set realtime priority to " << std::to_string(rt_priority_)
252 <<
", return code = " << status << TLOG_ENDL;
254 #pragma GCC diagnostic pop
259 TLOG_DEBUG(name_) <<
"Sending initial table." << TLOG_ENDL;
260 auto startTime = artdaq::MonitoredQuantity::getCurrentTime();
261 auto nextSendTime = startTime;
265 if (stop_requested_ || pause_requested_) {
break; }
266 startTime = artdaq::MonitoredQuantity::getCurrentTime();
268 if (startTime >= nextSendTime)
270 auto table = policy_->GetCurrentTable();
271 if (table.size() > 0) {
272 send_event_table(table);
273 ++table_update_count_;
274 delta_time = artdaq::MonitoredQuantity::getCurrentTime() - startTime;
275 statsHelper_.addSample(TABLE_UPDATES_STAT_KEY, delta_time);
276 TRACE(16,
"%s::process_fragments TABLE_UPDATES_STAT_KEY=%f", name_.c_str(), delta_time);
280 TLOG_WARNING(name_) <<
"No tokens received in this update interval! This is most likely a Very Bad Thing!" << TLOG_ENDL;
282 auto max_tokens = policy_->GetMaxNumberOfTokens();
283 if (max_tokens > 0) {
284 auto frac = table.size() /
static_cast<double>(max_tokens);
285 if (frac > 0.75) current_table_interval_ms_ = 9 * current_table_interval_ms_ / 10;
286 if (frac < 0.5) current_table_interval_ms_ = 11 * current_table_interval_ms_ / 10;
287 if (current_table_interval_ms_ > max_table_update_interval_ms_) current_table_interval_ms_ = max_table_update_interval_ms_;
288 if (current_table_interval_ms_ < 1) current_table_interval_ms_ = 1;
290 nextSendTime = startTime + current_table_interval_ms_ / 1000.0;
291 TLOG_DEBUG(name_) <<
"current_table_interval_ms is now " << current_table_interval_ms_ << TLOG_ENDL;
295 usleep(current_table_interval_ms_ * 10);
299 metricMan_.do_stop();
301 policy_.reset(
nullptr);
302 return table_update_count_;
308 if (table_socket_ == -1)
310 table_socket_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
313 TLOG_ERROR(name_) <<
"I failed to create the socket for sending Data Requests! Errno: " << std::to_string(errno) << TLOG_ENDL;
316 auto sts =
ResolveHost(send_tables_address_.c_str(), send_tables_port_, send_tables_addr_);
319 TLOG_ERROR(name_) <<
"Unable to resolve table_update_address" << TLOG_ENDL;
324 if (receive_address_ !=
"localhost") {
325 TLOG_DEBUG(name_) <<
"Making sure that multicast sending uses the correct interface for hostname " << receive_address_ << TLOG_ENDL;
330 throw art::Exception(art::errors::Configuration) <<
"RoutingMasterCore: Unable to resolve routing_master_address" << std::endl;;
333 if (setsockopt(table_socket_, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
335 throw art::Exception(art::errors::Configuration) <<
336 "RoutingMasterCore: Unable to enable port reuse on table update socket" << std::endl;
340 if (setsockopt(table_socket_, IPPROTO_IP, IP_MULTICAST_IF, &addr,
sizeof(addr)) == -1)
342 TLOG_ERROR(name_) <<
"Cannot set outgoing interface. Errno: " << std::to_string(errno) << TLOG_ENDL;
346 if (setsockopt(table_socket_, SOL_SOCKET, SO_BROADCAST, (
void*)&yes,
sizeof(
int)) == -1)
348 TLOG_ERROR(name_) <<
"Cannot set request socket to broadcast. Errno: " << std::to_string(errno) << TLOG_ENDL;
354 if (ack_socket_ == -1)
356 ack_socket_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
359 throw art::Exception(art::errors::Configuration) <<
"RoutingMasterCore: Error creating socket for receiving table update acks!" << std::endl;
363 struct sockaddr_in si_me_request;
366 if (setsockopt(ack_socket_, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
368 throw art::Exception(art::errors::Configuration) <<
369 "RoutingMasterCore: Unable to enable port reuse on ack socket" << std::endl;
372 memset(&si_me_request, 0,
sizeof(si_me_request));
373 si_me_request.sin_family = AF_INET;
374 si_me_request.sin_port = htons(receive_acks_port_);
375 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
376 if (bind(ack_socket_, reinterpret_cast<struct sockaddr *>(&si_me_request),
sizeof(si_me_request)) == -1)
378 throw art::Exception(art::errors::Configuration) <<
379 "RoutingMasterCore: Cannot bind request socket to port " << receive_acks_port_ << std::endl;
382 TLOG_DEBUG(name_) <<
"Listening for acks on 0.0.0.0 port " << receive_acks_port_ << TLOG_ENDL;
385 auto acks = std::unordered_map<int, bool>();
386 for (
auto& r : sender_ranks_)
391 auto start_time = std::chrono::steady_clock::now();
392 while (std::count_if(acks.begin(), acks.end(), [](std::pair<int, bool> p) {
return !p.second; }) > 0)
398 TLOG_DEBUG(name_) <<
"Sending table information for " << std::to_string(header.nEntries) <<
" events to multicast group " << send_tables_address_ <<
", port " << send_tables_port_ << TLOG_ENDL;
399 if (sendto(table_socket_, &header,
sizeof(
detail::RoutingPacketHeader), 0, reinterpret_cast<struct sockaddr *>(&send_tables_addr_),
sizeof(send_tables_addr_)) < 0)
401 TLOG_ERROR(name_) <<
"Error sending request message header" << TLOG_ENDL;
403 if (sendto(table_socket_, &packet[0], packetSize, 0, reinterpret_cast<struct sockaddr *>(&send_tables_addr_),
sizeof(send_tables_addr_)) < 0)
405 TLOG_ERROR(name_) <<
"Error sending request message data" << TLOG_ENDL;
410 auto first = packet[0].sequence_id;
411 auto last = packet.rbegin()->sequence_id;
412 TLOG_DEBUG(name_) <<
"Expecting acks to have first= " << std::to_string(first) <<
", and last= " << std::to_string(last) << TLOG_ENDL;
415 auto startTime = std::chrono::steady_clock::now();
416 while (std::count_if(acks.begin(), acks.end(), [](std::pair<int, bool> p) {
return !p.second; }) > 0)
418 auto currentTime = std::chrono::steady_clock::now();
419 auto table_ack_wait_time_ms = current_table_interval_ms_ / max_ack_cycle_count_;
420 if (static_cast<size_t>(std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count()) > table_ack_wait_time_ms)
422 if (counter > max_ack_cycle_count_ && table_update_count_ > 0)
424 TLOG_ERROR(name_) <<
"Did not receive acks from all senders after resending table " << std::to_string(counter) <<
" times during the table_update_interval. Check the status of the senders!" << TLOG_ENDL;
427 TLOG_WARNING(name_) <<
"Did not receive acks from all senders within the table_ack_wait_time. Resending table update" << TLOG_ENDL;
431 TLOG_ARB(20, name_) <<
"send_event_table: Polling Request socket for new requests" << TLOG_ENDL;
437 if (errno == EWOULDBLOCK || errno == EAGAIN) {
438 TLOG_ARB(20, name_) <<
"send_event_table: No more ack datagrams on ack socket." << TLOG_ENDL;
443 TLOG_ERROR(name_) <<
"An unexpected error occurred during ack packet receive" << TLOG_ENDL;
449 TLOG_DEBUG(name_) <<
"Ack packet from rank " << buffer.
rank <<
" has first= " << std::to_string(buffer.
first_sequence_id) <<
" and last= " << std::to_string(buffer.
last_sequence_id) << TLOG_ENDL;
452 TLOG_DEBUG(name_) <<
"Received table update acknowledgement from sender with rank " << std::to_string(buffer.
rank) <<
"." << TLOG_ENDL;
453 acks[buffer.
rank] =
true;
454 TLOG_DEBUG(name_) <<
"There are now " << std::count_if(acks.begin(), acks.end(), [](std::pair<int, bool> p) {
return !p.second; }) <<
" acks outstanding" << TLOG_ENDL;
458 if (!acks.count(buffer.
rank)) { TLOG_ERROR(name_) <<
"Received acknowledgement from invalid rank " << buffer.
rank <<
"! Cross-talk between RoutingMasters means there's a configuration error!" << TLOG_ENDL; }
459 else { TLOG_WARNING(name_) <<
"Received acknowledgement from rank " << buffer.
rank <<
" that had incorrect sequence ID information. Discarding." << TLOG_ENDL; }
463 usleep(table_ack_wait_time_ms * 1000 / 10);
468 std::chrono::duration<double, std::ratio<1>> delta = std::chrono::steady_clock::now() - start_time;
469 metricMan->sendMetric(
"Table Acknowledge Time", delta.count(),
"seconds", 3);
473 void artdaq::RoutingMasterCore::receive_tokens_()
475 while (!shutdown_requested_) {
476 TLOG_DEBUG(name_) <<
"Receive Token loop start" << TLOG_ENDL;
477 if (token_socket_ == -1)
479 TLOG_DEBUG(name_) <<
"Opening token listener socket" << TLOG_ENDL;
482 if (token_epoll_fd_ != -1) close(token_epoll_fd_);
483 struct epoll_event ev;
484 token_epoll_fd_ = epoll_create1(0);
485 ev.events = EPOLLIN | EPOLLPRI;
486 ev.data.fd = token_socket_;
487 if (epoll_ctl(token_epoll_fd_, EPOLL_CTL_ADD, token_socket_, &ev) == -1)
489 TLOG_ERROR(name_) <<
"Could not register listen socket to epoll fd" << TLOG_ENDL;
493 if (token_socket_ == -1 || token_epoll_fd_ == -1)
495 TLOG_DEBUG(name_) <<
"One of the listen sockets was not opened successfully." << TLOG_ENDL;
499 auto nfds = epoll_wait(token_epoll_fd_, &receive_token_events_[0], receive_token_events_.size(), current_table_interval_ms_);
501 perror(
"epoll_wait");
505 TLOG_DEBUG(name_) <<
"Received " << std::to_string(nfds) <<
" events" << TLOG_ENDL;
506 for (
auto n = 0; n < nfds; ++n) {
507 if (receive_token_events_[n].data.fd == token_socket_) {
508 TLOG_DEBUG(name_) <<
"Accepting new connection on token_socket" << TLOG_ENDL;
510 socklen_t arglen =
sizeof(addr);
511 auto conn_sock = accept(token_socket_, (
struct sockaddr *)&addr, &arglen);
513 if (conn_sock == -1) {
518 receive_token_addrs_[conn_sock] = std::string(inet_ntoa(addr.sin_addr));
519 struct epoll_event ev;
520 ev.events = EPOLLIN | EPOLLET;
521 ev.data.fd = conn_sock;
522 if (epoll_ctl(token_epoll_fd_, EPOLL_CTL_ADD, conn_sock, &ev) == -1) {
523 perror(
"epoll_ctl: conn_sock");
528 auto startTime = artdaq::MonitoredQuantity::getCurrentTime();
529 detail::RoutingToken buff;
530 auto sts = read(receive_token_events_[n].data.fd, &buff,
sizeof(detail::RoutingToken));
531 if (sts !=
sizeof(detail::RoutingToken) || buff.header != TOKEN_MAGIC)
533 TLOG_ERROR(name_) <<
"Received invalid token from " << receive_token_addrs_[receive_token_events_[n].data.fd] << TLOG_ENDL;
537 TLOG_DEBUG(name_) <<
"Received token from " << std::to_string(buff.rank) <<
" indicating " << buff.new_slots_free <<
" slots are free." << TLOG_ENDL;
538 received_token_count_ += buff.new_slots_free;
539 if (routing_mode_ == detail::RoutingMasterMode::RouteBySequenceID) {
540 policy_->AddReceiverToken(buff.rank, buff.new_slots_free);
542 else if (routing_mode_ == detail::RoutingMasterMode::RouteBySendCount)
544 if (!received_token_counter_.count(buff.rank)) received_token_counter_[buff.rank] = 0;
545 received_token_counter_[buff.rank] += buff.new_slots_free;
546 TLOG_DEBUG(name_) <<
"RoutingMasterMode is RouteBySendCount. I have " << received_token_counter_[buff.rank] <<
" tokens for rank " << buff.rank <<
" and I need " << sender_ranks_.size() <<
"." << TLOG_ENDL;
547 while (received_token_counter_[buff.rank] >= sender_ranks_.size()) {
548 TLOG_DEBUG(name_) <<
"RoutingMasterMode is RouteBySendCount. I have " << received_token_counter_[buff.rank] <<
" tokens for rank " << buff.rank <<
" and I need " << sender_ranks_.size()
549 <<
"... Sending token to policy" << TLOG_ENDL;
550 policy_->AddReceiverToken(buff.rank, 1);
551 received_token_counter_[buff.rank] -= sender_ranks_.size();
555 auto delta_time = artdaq::MonitoredQuantity::getCurrentTime() - startTime;
556 statsHelper_.addSample(TOKENS_RECEIVED_STAT_KEY, delta_time);
563 void artdaq::RoutingMasterCore::start_recieve_token_thread_()
565 if (ev_token_receive_thread_.joinable()) ev_token_receive_thread_.join();
566 TLOG_INFO(name_) <<
"Starting Token Reception Thread" << TLOG_ENDL;
567 ev_token_receive_thread_ = std::thread(&RoutingMasterCore::receive_tokens_,
this);
572 std::string resultString;
575 auto tmpString = name_ +
" run number = " + std::to_string(run_id_.run())
576 +
", table updates sent = " + std::to_string(table_update_count_)
577 +
", Receiver tokens received = " + std::to_string(received_token_count_);
581 std::string artdaq::RoutingMasterCore::buildStatisticsString_()
const
583 std::ostringstream oss;
584 oss << name_ <<
" statistics:" << std::endl;
586 auto mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(TABLE_UPDATES_STAT_KEY);
587 if (mqPtr.get() !=
nullptr)
589 artdaq::MonitoredQuantityStats stats;
590 mqPtr->getStats(stats);
591 oss <<
" Table Update statistics: "
592 << stats.recentSampleCount <<
" table updates sent at "
593 << stats.recentSampleRate <<
" table updates/sec, , monitor window = "
594 << stats.recentDuration <<
" sec" << std::endl;
595 oss <<
" Average times per table update: ";
596 if (stats.recentSampleRate > 0.0)
598 oss <<
" elapsed time = "
599 << (1.0 / stats.recentSampleRate) <<
" sec";
601 oss <<
", avg table acknowledgement wait time = "
602 << (mqPtr->getRecentValueSum() / sender_ranks_.size()) <<
" sec" << std::endl;
605 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(TOKENS_RECEIVED_STAT_KEY);
606 if (mqPtr.get() !=
nullptr)
608 artdaq::MonitoredQuantityStats stats;
609 mqPtr->getStats(stats);
610 oss <<
" Received Token statistics: "
611 << stats.recentSampleCount <<
" tokens received at "
612 << stats.recentSampleRate <<
" tokens/sec, , monitor window = "
613 << stats.recentDuration <<
" sec" << std::endl;
614 oss <<
" Average times per token: ";
615 if (stats.recentSampleRate > 0.0)
617 oss <<
" elapsed time = "
618 << (1.0 / stats.recentSampleRate) <<
" sec";
620 oss <<
", input token wait time = "
621 << mqPtr->getRecentValueSum() <<
" sec" << std::endl;
627 void artdaq::RoutingMasterCore::sendMetrics_()
629 auto mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(TABLE_UPDATES_STAT_KEY);
630 if (mqPtr.get() !=
nullptr)
632 artdaq::MonitoredQuantityStats stats;
633 mqPtr->getStats(stats);
634 metricMan_.sendMetric(
"Table Update Count",
635 static_cast<unsigned long>(stats.fullSampleCount),
637 metricMan_.sendMetric(
"Table Update Rate",
638 stats.recentSampleRate,
"updates/sec", 1);
640 metricMan_.sendMetric(
"Average Sender Acknowledgement Time",
641 (mqPtr->getRecentValueSum() / sender_ranks_.size()),
642 "seconds", 3,
false);
645 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(TOKENS_RECEIVED_STAT_KEY);
646 if (mqPtr.get() !=
nullptr)
648 artdaq::MonitoredQuantityStats stats;
649 mqPtr->getStats(stats);
650 metricMan_.sendMetric(
"Receiver Token Count",
651 static_cast<unsigned long>(stats.fullSampleCount),
653 metricMan_.sendMetric(
"Receiver Token Rate",
654 stats.recentSampleRate,
"updates/sec", 1);
655 metricMan_.sendMetric(
"Total Receiver Token Wait Time",
656 mqPtr->getRecentValueSum(),
657 "seconds", 3,
false);
bool resume(uint64_t, uint64_t)
Resumes the RoutingMasterCore.
size_t process_event_table()
Main loop of the RoutingMasterCore. Determines when to send the next table update, asks the RoutingMasterPolicy for the table to send, and sends it.
void addMonitoredQuantityName(std::string const &statKey)
Add a MonitoredQuantity name to the list.
int ResolveHost(char const *host_in, in_addr &addr)
Convert a string hostname to a in_addr suitable for socket communication.
bool soft_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Soft-Initializes the RoutingMasterCore.
static const std::string TOKENS_RECEIVED_STAT_KEY
Key for the Tokens Received MonitoredQuantity.
A row of the Routing Table.
bool reinitialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Reinitializes the RoutingMasterCore.
bool start(art::RunID id, uint64_t, uint64_t)
Start the RoutingMasterCore.
A RoutingAckPacket contains the rank of the table receiver, plus the first and last sequence IDs in t...
RoutingMasterCore(int rank, std::string name)
RoutingMasterCore Constructor.
bool initialize(fhicl::ParameterSet const &pset, uint64_t, uint64_t)
Processes the initialize request.
The RoutingToken contains the magic bytes, the rank of the token sender, and the number of slots free...
int TCP_listen_fd(int port, int rcvbuf)
Create a TCP listening socket on the given port and INADDR_ANY, with the given receive buffer...
Fragment::sequence_id_t first_sequence_id
The first sequence ID in the received RoutingPacket.
bool pause(uint64_t, uint64_t)
Pauses the RoutingMasterCore.
Fragment::sequence_id_t last_sequence_id
The last sequence ID in the received RoutingPacket.
std::vector< RoutingPacketEntry > RoutingPacket
A RoutingPacket is simply a vector of RoutingPacketEntry objects. It is not suitable for network tran...
bool stop(uint64_t, uint64_t)
Stops the RoutingMasterCore.
int rank
The rank from which the RoutingAckPacket came.
std::unique_ptr< RoutingMasterPolicy > makeRoutingMasterPolicy(std::string const &policy_plugin_spec, fhicl::ParameterSet const &ps)
Load a RoutingMasterPolicy plugin.
std::string report(std::string const &) const
Send a report on the current status of the RoutingMasterCore.
static const std::string TABLE_UPDATES_STAT_KEY
Key for Table Update count MonnitoredQuantity.
bool shutdown(uint64_t)
Shuts Down the RoutingMasterCore.
void send_event_table(detail::RoutingPacket table)
Sends a detail::RoutingPacket to the table receivers.