Line data Source code
1 : #ifndef ARTDAQ_PROTO_ARTDAQAPP_HH
2 : #define ARTDAQ_PROTO_ARTDAQAPP_HH
3 :
4 : #include "artdaq/DAQdata/Globals.hh"
5 :
6 : #include "artdaq-core/Utilities/ExceptionHandler.hh"
7 : #include "artdaq-core/Utilities/configureMessageFacility.hh"
8 : #include "artdaq/Application/BoardReaderApp.hh"
9 : #include "artdaq/Application/DataLoggerApp.hh"
10 : #include "artdaq/Application/DispatcherApp.hh"
11 : #include "artdaq/Application/EventBuilderApp.hh"
12 : #include "artdaq/Application/RoutingManagerApp.hh"
13 : #include "artdaq/Application/TaskType.hh"
14 : #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
15 : #include "artdaq/ExternalComms/MakeCommanderPlugin.hh"
16 :
17 : #include <sys/prctl.h>
18 :
19 : namespace artdaq {
20 : /// <summary>
21 : /// Class representing an artdaq application. Used by all "main" functions to start artdaq.
22 : /// </summary>
23 : class artdaqapp
24 : {
25 : public:
26 : /// <summary>
27 : /// Configuration of artdaqapp. May be used for parameter validation
28 : /// </summary>
29 : struct Config
30 : {
31 : /// "application_name" (Default: artdaq::detail::TaskTypeToString(task)): Name to use for metrics and logging
32 : fhicl::Atom<std::string> application_name{fhicl::Name{"application_name"}, fhicl::Comment{"Name to use for metrics and logging"}, "BoardReader"};
33 : /// "replace_image_name" (Default: false): Replace the application image name with application_name
34 : fhicl::Atom<bool> replace_image_name{fhicl::Name{"replace_image_name"}, fhicl::Comment{"Replace the application image name with application_name"}, false};
35 : /// "rank": The "rank" of the application, used for configuring data transfers
36 : fhicl::Atom<int> rank{fhicl::Name{"rank"}, fhicl::Comment{"The \"rank\" of the application, used for configuring data transfers"}};
37 : fhicl::TableFragment<artdaq::CommanderInterface::Config> commanderPluginConfig; ///< Configuration for the CommanderInterface. See artdaq::CommanderInterface::Config
38 : /// "auto_run" (Default: false): Whether to automatically start a run
39 : fhicl::Atom<bool> auto_run{fhicl::Name{"auto_run"}, fhicl::Comment{"Whether to automatically start a run"}, false};
40 : /// "run_number" (Default: 101): Run number to use for automatic run
41 : fhicl::Atom<int> run_number{fhicl::Name{"run_number"}, fhicl::Comment{"Run number to use for automatic run"}, 101};
42 : /// "transition_timeout" (Default: 30): Timeout to use for automatic transitions
43 : fhicl::Atom<uint64_t> transition_timeout{fhicl::Name{"transition_timeout"}, fhicl::Comment{"Timeout to use for automatic transitions"}, 30};
44 : fhicl::TableFragment<artdaq::PortManager::Config> portsConfig; ///< Configuration for artdaq Ports
45 : };
46 : /// Used for ParameterSet validation (if desired)
47 : using Parameters = fhicl::WrappedTable<Config>;
48 :
49 : /// <summary>
50 : /// Run an artdaq Application
51 : /// </summary>
52 : /// <param name="task">Task type of the application</param>
53 : /// <param name="config_ps">"Startup" parameter set. See artdaq::artdaqapp::Config</param>
54 0 : static void runArtdaqApp(detail::TaskType task, fhicl::ParameterSet const& config_ps)
55 : {
56 0 : app_name = config_ps.get<std::string>("application_name", detail::TaskTypeToString(task));
57 0 : portMan->UpdateConfiguration(config_ps);
58 :
59 0 : if (config_ps.get<bool>("replace_image_name", config_ps.get<bool>("rin", false)))
60 : {
61 : int s;
62 0 : s = prctl(PR_SET_NAME, app_name.c_str(), NULL, NULL, NULL);
63 0 : if (s != 0)
64 : {
65 0 : std::cerr << "Could not replace process image name with " << app_name << "!" << std::endl;
66 0 : exit(1);
67 : }
68 : }
69 :
70 0 : std::string mf_app_name = artdaq::setMsgFacAppName(app_name, config_ps.get<int>("id"));
71 : try
72 : {
73 0 : artdaq::configureMessageFacility(mf_app_name.c_str());
74 : }
75 0 : catch (cet::exception const&)
76 : {
77 0 : ExceptionHandler(ExceptionHandlerRethrow::yes, "Exception occurred while setting up MessageFacility");
78 0 : }
79 :
80 0 : if (config_ps.has_key("rank"))
81 : {
82 0 : my_rank = config_ps.get<int>("rank");
83 : }
84 0 : TLOG_DEBUG(app_name + "Main") << "Setting application name to " << app_name;
85 :
86 : // 23-May-2018, KAB: added lookup of the partition number from the command line arguments.
87 0 : if (config_ps.has_key("partition_number"))
88 : {
89 0 : artdaq::Globals::partition_number_ = config_ps.get<int>("partition_number");
90 : }
91 0 : TLOG_DEBUG(app_name + "Main") << "Setting partition number to " << artdaq::Globals::partition_number_;
92 :
93 0 : TLOG_DEBUG(app_name + "Main") << "artdaq version " << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
94 0 : << ", built " << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
95 :
96 0 : artdaq::setMsgFacAppName(app_name, config_ps.get<int>("id"));
97 :
98 0 : std::unique_ptr<artdaq::Commandable> comm(nullptr);
99 0 : switch (task)
100 : {
101 0 : case (detail::BoardReaderTask):
102 0 : comm = std::make_unique<BoardReaderApp>();
103 0 : break;
104 0 : case (detail::EventBuilderTask):
105 0 : comm = std::make_unique<EventBuilderApp>();
106 0 : break;
107 0 : case (detail::DataLoggerTask):
108 0 : comm = std::make_unique<DataLoggerApp>();
109 0 : break;
110 0 : case (detail::DispatcherTask):
111 0 : comm = std::make_unique<DispatcherApp>();
112 0 : break;
113 0 : case (detail::RoutingManagerTask):
114 0 : comm = std::make_unique<RoutingManagerApp>();
115 0 : break;
116 0 : default:
117 0 : return;
118 : }
119 :
120 0 : auto auto_run = config_ps.get<bool>("auto_run", false);
121 0 : if (auto_run)
122 : {
123 0 : auto run = config_ps.get<int>("run_number", 101);
124 0 : auto timeout = config_ps.get<uint64_t>("transition_timeout", 30);
125 0 : uint64_t timestamp = 0;
126 :
127 0 : comm->do_initialize(config_ps, timeout, timestamp);
128 0 : comm->do_start(art::RunID(run), timeout, timestamp);
129 :
130 0 : TLOG_INFO(app_name + "Main") << "Running XMLRPC Commander. To stop, either Control-C or " << std::endl
131 0 : << "xmlrpc http://`hostname`:" << config_ps.get<int>("id") << "/RPC2 daq.stop" << std::endl
132 0 : << "xmlrpc http://`hostname`:" << config_ps.get<int>("id") << "/RPC2 daq.shutdown";
133 : }
134 :
135 0 : auto commander = artdaq::MakeCommanderPlugin(config_ps, *comm);
136 0 : commander->run_server();
137 0 : artdaq::Globals::CleanUpGlobals();
138 0 : }
139 : };
140 : } // namespace artdaq
141 :
142 : #endif // ARTDAQ_PROTO_ARTDAQAPP_HH
|