1 #include "TRACE/tracemf.h"
2 #include "artdaq/DAQdata/Globals.hh"
3 #define TRACE_NAME (app_name + "_DispatcherCore").c_str()
5 #include "artdaq/Application/DispatcherCore.hh"
7 #include "fhiclcpp/ParameterSet.h"
9 #include <boost/algorithm/string.hpp>
10 #include <boost/exception/all.hpp>
11 #include <boost/throw_exception.hpp>
12 #include <boost/tokenizer.hpp>
21 #include <unordered_map>
27 TLOG(TLVL_DEBUG + 32) <<
"initialize method called with DAQ "
28 <<
"ParameterSet = \"" << pset.to_string() <<
"\".";
32 if (pset_.has_key(
"art"))
34 pset_ = pset_.get<fhicl::ParameterSet>(
"art");
36 pset_.erase(
"outputs");
37 pset_.erase(
"physics");
40 TLOG(TLVL_DEBUG + 32) <<
"Pieces of the input pset that are saved for later: \"" << pset_.to_string() <<
"\".";
43 fhicl::ParameterSet daq_pset;
46 daq_pset = pset.get<fhicl::ParameterSet>(
"daq");
51 <<
"Unable to find the DAQ parameters in the initialization "
52 <<
"ParameterSet: \"" + pset.to_string() +
"\".";
55 fhicl::ParameterSet agg_pset;
58 agg_pset = daq_pset.get<fhicl::ParameterSet>(
"dispatcher", daq_pset.get<fhicl::ParameterSet>(
"aggregator"));
63 <<
"Unable to find the Dispatcher parameters in the DAQ "
64 <<
"initialization ParameterSet: \"" + daq_pset.to_string() +
"\".";
68 broadcast_mode_ = agg_pset.get<
bool>(
"broadcast_mode",
true);
69 if (broadcast_mode_ && !agg_pset.has_key(
"broadcast_mode"))
71 agg_pset.put<
bool>(
"broadcast_mode",
true);
72 if (!agg_pset.has_key(
"non_reliable_mode"))
74 agg_pset.put<
bool>(
"non_reliable_mode",
true);
76 if (!agg_pset.has_key(
"non_reliable_mode_retry_count"))
78 agg_pset.put<
int>(
"non_reliable_mode_retry_count", 2);
82 agg_pset.erase(
"restart_crashed_art_processes");
83 agg_pset.put<
bool>(
"restart_crashed_art_processes",
false);
85 agg_pset.erase(
"art_analyzer_count");
86 agg_pset.put<
int>(
"art_analyzer_count", 0);
89 fhicl::ParameterSet metric_pset = daq_pset.get<fhicl::ParameterSet>(
"metrics", fhicl::ParameterSet());
96 TLOG(TLVL_DEBUG + 32) <<
"DispatcherCore::register_monitor called with argument \"" << pset.to_string() <<
"\"";
99 if (stop_requested_.load())
101 TLOG(TLVL_WARNING) <<
"DispatcherCore::register_monitor called after stop. NOT registering new monitor!";
107 TLOG(TLVL_DEBUG + 32) <<
"Getting unique_label from input ParameterSet";
108 auto const& label = pset.get<std::string>(
"unique_label");
109 TLOG(TLVL_DEBUG + 32) <<
"Unique label is " << label;
111 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
112 if (registered_monitors_.count(label) != 0u)
114 throw cet::exception(
"DispatcherCore") <<
"Unique label already exists!";
117 registered_monitors_[label] = pset;
121 boost::thread thread([=] { start_art_process_(label); });
124 catch (
const cet::exception& e)
126 std::stringstream errmsg;
127 errmsg <<
"Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() <<
"\", a new monitor has not been registered" << std::endl;
128 errmsg <<
"Exception: " << e.what();
129 TLOG(TLVL_ERROR) << errmsg.str();
132 catch (
const boost::exception& e)
134 std::stringstream errmsg;
135 errmsg <<
"Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() <<
"\", a new monitor has not been registered" << std::endl;
136 errmsg <<
"Exception: " << boost::diagnostic_information(e);
137 TLOG(TLVL_ERROR) << errmsg.str();
140 catch (
const std::exception& e)
142 std::stringstream errmsg;
143 errmsg <<
"Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() <<
"\", a new monitor has not been registered" << std::endl;
144 errmsg <<
"Exception: " << e.what();
145 TLOG(TLVL_ERROR) << errmsg.str();
150 std::stringstream errmsg;
151 errmsg <<
"Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() <<
"\", a new monitor has not been registered";
152 TLOG(TLVL_ERROR) << errmsg.str();
156 TLOG(TLVL_DEBUG + 32) <<
"Successfully registered monitor";
162 TLOG(TLVL_DEBUG + 32) <<
"DispatcherCore::unregister_monitor called with argument \"" << label <<
"\"";
168 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
169 if (registered_monitors_.count(label) == 0)
171 std::stringstream errmsg;
172 errmsg <<
"Warning in DispatcherCore::unregister_monitor: unable to find requested transfer plugin with "
173 <<
"label \"" << label <<
"\"";
174 TLOG(TLVL_WARNING) << errmsg.str();
178 registered_monitors_.erase(label);
182 boost::thread thread([=] { stop_art_process_(label); });
187 std::stringstream errmsg;
188 errmsg <<
"Unable to unregister transfer plugin with label \"" << label <<
"\"";
189 TLOG(TLVL_ERROR) << errmsg.str();
193 TLOG(TLVL_DEBUG + 32) <<
"unregister_monitor completed successfully";
197 fhicl::ParameterSet artdaq::DispatcherCore::merge_parameter_sets_(fhicl::ParameterSet
const& skel,
const std::string& label,
const fhicl::ParameterSet& pset)
199 fhicl::ParameterSet generated_pset(skel);
200 fhicl::ParameterSet generated_outputs;
201 fhicl::ParameterSet generated_physics;
202 fhicl::ParameterSet generated_physics_analyzers;
203 fhicl::ParameterSet generated_physics_producers;
204 fhicl::ParameterSet generated_physics_filters;
205 std::unordered_map<std::string, std::vector<std::string>> generated_physics_filter_paths;
207 TLOG(TLVL_DEBUG + 32) <<
"merge_parameter_sets_: Generating fhicl for monitor " << label;
211 auto path = pset.get<std::vector<std::string>>(
"path");
213 auto filters = pset.get<std::vector<fhicl::ParameterSet>>(
"filter_paths", std::vector<fhicl::ParameterSet>());
214 for (
auto& filter : filters)
218 auto name = filter.get<std::string>(
"name");
219 auto path = filter.get<std::vector<std::string>>(
"path");
220 if (generated_physics_filter_paths.count(name) != 0u)
222 bool matched = generated_physics_filter_paths[name].size() == path.size();
223 for (
size_t ii = 0; matched && ii < generated_physics_filter_paths[name].size(); ++ii)
225 matched = matched && path[ii] == generated_physics_filter_paths[name][ii];
234 auto newname = label + name;
235 generated_physics_filter_paths[newname] = path;
239 generated_physics_filter_paths[name] = path;
248 auto outputs = pset.get<fhicl::ParameterSet>(
"outputs");
249 if (outputs.get_pset_names().size() > 1 || outputs.get_pset_names().empty())
253 auto output_name = outputs.get_pset_names()[0];
254 auto output_pset = outputs.get<fhicl::ParameterSet>(output_name);
255 generated_outputs.put(label + output_name, output_pset);
256 bool outputInPath =
false;
257 for (
auto& ii : path)
259 if (ii == output_name)
261 ii = label + output_name;
267 path.push_back(label + output_name);
271 auto physics_pset = pset.get<fhicl::ParameterSet>(
"physics");
273 if (physics_pset.has_key(
"analyzers"))
275 auto analyzers = physics_pset.get<fhicl::ParameterSet>(
"analyzers");
276 for (
const auto& key : analyzers.get_pset_names())
278 if (generated_physics_analyzers.has_key(key) && analyzers.get<fhicl::ParameterSet>(key) == generated_physics_analyzers.get<fhicl::ParameterSet>(key))
283 if (generated_physics_analyzers.has_key(key))
286 auto newkey = label + key;
287 generated_physics_analyzers.put<fhicl::ParameterSet>(newkey, analyzers.get<fhicl::ParameterSet>(key));
288 for (
auto& ii : path)
298 generated_physics_analyzers.put<fhicl::ParameterSet>(key, analyzers.get<fhicl::ParameterSet>(key));
302 if (physics_pset.has_key(
"producers"))
304 auto producers = physics_pset.get<fhicl::ParameterSet>(
"producers");
305 for (
const auto& key : producers.get_pset_names())
307 if (generated_physics_producers.has_key(key) && producers.get<fhicl::ParameterSet>(key) == generated_physics_producers.get<fhicl::ParameterSet>(key))
312 if (generated_physics_producers.has_key(key))
315 auto newkey = label + key;
316 generated_physics_producers.put<fhicl::ParameterSet>(newkey, producers.get<fhicl::ParameterSet>(key));
317 for (
auto& ii : path)
327 generated_physics_producers.put<fhicl::ParameterSet>(key, producers.get<fhicl::ParameterSet>(key));
331 if (physics_pset.has_key(
"filters"))
333 auto filters = physics_pset.get<fhicl::ParameterSet>(
"filters");
334 for (
const auto& key : filters.get_pset_names())
336 if (generated_physics_filters.has_key(key) && filters.get<fhicl::ParameterSet>(key) == generated_physics_filters.get<fhicl::ParameterSet>(key))
341 if (generated_physics_filters.has_key(key))
344 auto newkey = label + key;
345 generated_physics_filters.put<fhicl::ParameterSet>(newkey, filters.get<fhicl::ParameterSet>(key));
346 for (
auto& ii : path)
356 generated_physics_filters.put<fhicl::ParameterSet>(key, filters.get<fhicl::ParameterSet>(key));
360 generated_physics.put<std::vector<std::string>>(label, path);
362 catch (cet::exception& e)
365 TLOG(TLVL_ERROR) <<
"merge_parameter_sets_: Error processing input fhicl: " << e.what();
368 TLOG(TLVL_DEBUG + 32) <<
"merge_parameter_sets_: Building final ParameterSet";
369 generated_pset.put(
"outputs", generated_outputs);
371 generated_physics.put(
"analyzers", generated_physics_analyzers);
372 generated_physics.put(
"producers", generated_physics_producers);
373 generated_physics.put(
"filters", generated_physics_filters);
375 for (
auto& path : generated_physics_filter_paths)
377 generated_physics.put(path.first, path.second);
380 generated_pset.put(
"physics", generated_physics);
382 return generated_pset;
385 fhicl::ParameterSet artdaq::DispatcherCore::generate_filter_fhicl_()
387 TLOG(TLVL_DEBUG + 32) <<
"generate_filter_fhicl_ BEGIN";
388 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
389 fhicl::ParameterSet generated_pset = pset_;
391 for (
auto& monitor : registered_monitors_)
393 auto label = monitor.first;
394 auto pset = monitor.second;
395 generated_pset = merge_parameter_sets_(generated_pset, label, pset);
398 TLOG(TLVL_DEBUG + 32) <<
"generate_filter_fhicl_ returning ParameterSet: " << generated_pset.to_string();
399 return generated_pset;
402 void artdaq::DispatcherCore::check_filters_()
404 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
405 auto it = registered_monitors_.begin();
406 while (it != registered_monitors_.end())
408 if (registered_monitor_pids_.count(it->first) != 0u)
410 if (!event_store_ptr_)
412 registered_monitor_pids_.erase(it->first);
416 auto pid = registered_monitor_pids_[it->first];
417 auto sts = kill(pid, 0);
420 registered_monitor_pids_.erase(it->first);
428 void artdaq::DispatcherCore::start_art_process_(std::string
const& label)
430 if (event_store_ptr_ !=
nullptr)
434 fhicl::ParameterSet pset;
436 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
437 pset = registered_monitors_[label];
439 fhicl::ParameterSet ps = merge_parameter_sets_(pset_, label, pset);
440 TLOG(TLVL_DEBUG + 32) <<
"Starting art process with received fhicl";
441 auto pid = event_store_ptr_->StartArtProcess(ps, registered_monitors_.size() - 1);
443 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
444 registered_monitor_pids_[label] = pid;
449 TLOG(TLVL_DEBUG + 32) <<
"Calling ReconfigureArt";
450 fhicl::ParameterSet generated_fhicl;
452 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
453 generated_fhicl = generate_filter_fhicl_();
455 event_store_ptr_->ReconfigureArt(generated_fhicl);
456 TLOG(TLVL_DEBUG + 32) <<
"Done with ReconfigureArt";
461 TLOG(TLVL_ERROR) <<
"Unable to add monitor as there is no SharedMemoryEventManager instance!";
465 void artdaq::DispatcherCore::stop_art_process_(std::string
const& label)
467 if (event_store_ptr_ !=
nullptr)
471 if (registered_monitor_pids_.count(label) != 0u)
473 std::set<pid_t> pids;
475 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
476 pids.insert(registered_monitor_pids_[label]);
477 registered_monitor_pids_.erase(label);
479 TLOG(TLVL_DEBUG + 32) <<
"Calling ShutdownArtProcesses";
480 event_store_ptr_->ShutdownArtProcesses(pids);
481 TLOG(TLVL_DEBUG + 32) <<
"Done with ShutdownArtProcesses";
486 TLOG(TLVL_DEBUG + 32) <<
"Calling ReconfigureArt";
487 fhicl::ParameterSet generated_fhicl;
489 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
490 generated_fhicl = generate_filter_fhicl_();
492 event_store_ptr_->ReconfigureArt(generated_fhicl);
493 TLOG(TLVL_DEBUG + 32) <<
"Done with ReconfigureArt";
std::string unregister_monitor(std::string const &label)
Delete the TransferInterface having the given unique label.
std::string register_monitor(fhicl::ParameterSet const &pset)
Create a new TransferInterface instance using the given configuration.
bool initializeDataReceiver(fhicl::ParameterSet const &pset, fhicl::ParameterSet const &data_pset, fhicl::ParameterSet const &metric_pset)
Initialize the DataReceiverCore (should be called from initialize() overrides.
bool initialize(fhicl::ParameterSet const &pset) override
Processes the initialize request.