DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
disabled-components.cpp
Go to the documentation of this file.
7#include "confmodel/util.hpp"
9
10#include "logging/Logging.hpp"
11
13
14using namespace dunedaq::conffwk;
15using namespace dunedaq::confmodel;
16
19 m_db(db),
20 m_session(session),
21 m_num_of_slr_enabled_resources(0),
22 m_num_of_slr_disabled_resources(0)
23{
24 TLOG_DEBUG(2) << "construct the object " << (void *)this ;
25 m_db.add_action(this);
26}
27
29{
30 TLOG_DEBUG(2) << "destroy the object " << (void *)this ;
31 m_db.remove_action(this);
32}
33
34void
35DisabledComponents::notify(std::vector<ConfigurationChange *>& /*changes*/) noexcept
36{
37 TLOG_DEBUG(2) << "reset session components because of notification callback on object " << (void *)this ;
38 __clear();
39}
40
41void
43{
44 TLOG_DEBUG(2) << "reset session components because of configuration load on object " << (void *)this ;
45 __clear();
46}
47
48void
50{
51 TLOG_DEBUG(2) << "reset session components because of configuration unload on object " << (void *)this ;
52 __clear();
53}
54
55void
56DisabledComponents::update(const ConfigObject& obj, const std::string& name) noexcept
57{
58 TLOG_DEBUG(2) << "reset session components because of configuration update (obj = " << obj << ", name = \'" << name << "\') on object " << (void *)this ;
59 __clear();
60}
61
62void
64{
65 TLOG_DEBUG(2) << "reset disabled by explicit user call" ;
66 m_disabled.clear(); // do not clear s_user_disabled && s_user_enabled !!!
67}
68
69
70void
72{
73 for (auto & res : rs.get_contains()) {
74 disable(*res);
75 if (const auto * rs2 = res->cast<ResourceSet>()) {
76 disable_children(*rs2);
77 }
78 }
79}
80
81void
83{
84 for (auto & app : segment.get_applications()) {
85 auto res = app->cast<Component>();
86 if (res) {
87 disable(*res);
88 }
89 }
90 for (auto & seg : segment.get_segments()) {
91 TLOG_DEBUG(6) << "disable segment " << seg << " because it's parent segment " << &segment << " is disabled" ;
92 disable(*seg);
93 disable_children(*seg);
94 }
95}
96
97void
98Session::set_disabled(const std::set<const Component *>& objs) const
99{
101
102 for (const auto& comp : objs) {
104 }
106
108}
109
110void
111Session::set_enabled(const std::set<const Component *>& objs) const
112{
114
115 for (const auto& i : objs) {
117 }
119
121}
123
124namespace dunedaq {
126 confmodel,
127 ReadMaxAllowedIterations,
129 "Has exceeded the maximum of iterations allowed (" << limit << ") during calculation of disabled objects",
130 ,
131 ((unsigned int)limit)
132 )
133}
134
136
137 // fill data from resource sets
138
139static void fill(
140 const ResourceSet& rs,
141 std::vector<const ResourceSetOR *>& rs_or,
142 std::vector<const ResourceSetAND *>& rs_and,
144)
145{
146 if (const ResourceSetAND * r1 = rs.cast<ResourceSetAND>())
147 {
148 rs_and.push_back(r1);
149 }
150 else if (const ResourceSetOR * r2 = rs.cast<ResourceSetOR>())
151 {
152 rs_or.push_back(r2);
153 }
154
155 for (auto & i : rs.get_contains())
156 {
157 AddTestOnCircularDependency add_fuse_test(cd_fuse, i);
158 if (const ResourceSet * rs2 = i->cast<ResourceSet>())
159 {
160 fill(*rs2, rs_or, rs_and, cd_fuse);
161 }
162 }
163}
164
165
166 // fill data from segments
167
168static void fill(
169 const Segment& s,
170 std::vector<const ResourceSetOR *>& rs_or,
171 std::vector<const ResourceSetAND *>& rs_and,
173)
174{
175 for (auto & app : s.get_applications()) {
176 AddTestOnCircularDependency add_fuse_test(cd_fuse, app);
177 if (const ResourceSet * rs = app->cast<ResourceSet>()) {
178 fill(*rs, rs_or, rs_and, cd_fuse);
179 }
180 }
181
182 for (auto & seg : s.get_segments()) {
183 TLOG_DEBUG(6) << "Filling segment " << seg->UID();
184 AddTestOnCircularDependency add_fuse_test(cd_fuse, seg);
185 fill(*seg, rs_or, rs_and, cd_fuse);
186 }
187}
188
189
190 // fill data from session
191
192static void fill(
193 const Session& session,
194 std::vector<const ResourceSetOR *>& rs_or,
195 std::vector<const ResourceSetAND *>& rs_and,
197)
198{
199#if 0
200 if (const OnlineSegment * onlseg = p.get_OnlineInfrastructure())
201 {
202 AddTestOnCircularDependency add_fuse_test(cd_fuse, onlseg);
203 fill(*onlseg, rs_or, rs_and, cd_fuse);
204
205 // NOTE: normally application may not be ResourceSet, but for some "exotic" cases put this code
206 for (auto &a : p.get_OnlineInfrastructureApplications())
207 {
208 if (const ResourceSet * rs = a->cast<ResourceSet>())
209 {
210 fill(*rs, rs_or, rs_and, cd_fuse);
211 }
212 }
213 }
214#endif
215
216 auto seg = session.get_segment();
217 AddTestOnCircularDependency add_fuse_test(cd_fuse, seg);
218 fill(*seg, rs_or, rs_and, cd_fuse);
219}
220
222
223bool
225{
226 TLOG_DEBUG( 6) << "Session UID: " << session.UID() << " this->UID()=" << UID();
227 // fill disabled (e.g. after session changes)
228
229 if (session.m_disabled_components.size() == 0) {
230 if (session.get_disabled().empty() &&
231 session.m_disabled_components.m_user_disabled.empty()) {
232 TLOG_DEBUG( 6) << "Session has no disabled components";
233 return false; // the session has no disabled components
234 }
235 else {
236 // get two lists of all session's resource-set-or and resource-set-and
237 // also test any circular dependencies between segments and resource sets
238 TestCircularDependency cd_fuse("component \'is-disabled\' status", &session);
239 std::vector<const ResourceSetOR *> rs_or;
240 std::vector<const ResourceSetAND *> rs_and;
241 fill(session, rs_or, rs_and, cd_fuse);
242
243 // calculate explicitly and implicitly (nested) disabled components
244 {
245 std::vector<const Component *> vector_of_disabled;
246 vector_of_disabled.reserve(session.get_disabled().size() + session.m_disabled_components.m_user_disabled.size());
247
248 // add user disabled components, if any
249 for (auto & i : session.m_disabled_components.m_user_disabled) {
250 vector_of_disabled.push_back(i);
251 TLOG_DEBUG(6) << "disable component " << i->UID() << " because it is explicitly disabled by user" ;
252 }
253
254 // add session-disabled components ignoring explicitly enabled by user
255 for (auto & i : session.get_disabled()) {
256 TLOG_DEBUG(6) << "check component " << i->UID() << " explicitly disabled in session" ;
257
258 if (session.m_disabled_components.m_user_enabled.find(i) == session.m_disabled_components.m_user_enabled.end()) {
259 vector_of_disabled.push_back(i);
260 TLOG_DEBUG(6) << "disable component " << i->UID() << " because it is not explicitly enabled in session" ;
261 }
262 else {
263 TLOG_DEBUG(6) << "skip component " << i->UID() << " because it is enabled by user" ;
264 }
265 }
266
267 // fill set of explicitly and implicitly (segment/resource-set containers) disabled components
268 for (auto & i : vector_of_disabled) {
269 session.m_disabled_components.disable(*i);
270
271 if (const ResourceSet * rs = i->cast<ResourceSet>()) {
272 session.m_disabled_components.disable_children(*rs);
273 }
274 else if (const Segment * seg = i->cast<Segment>()) {
275 TLOG_DEBUG(6) << "Disabling children of segment " << seg->UID();
276 session.m_disabled_components.disable_children(*seg);
277 }
278 }
279 }
280
281 for (unsigned long count = 1; true; ++count) {
282 const unsigned long num(session.m_disabled_components.size());
283
284 TLOG_DEBUG(6) << "before auto-disabling iteration " << count << " the number of disabled components is " << num ;
285
286 TLOG_DEBUG(6) << "Session has " << rs_or.size() << " resourceSetORs";
287 for (const auto& i : rs_or) {
288 if (session.m_disabled_components.is_enabled(i)) {
289 // check ANY child is disabled
290 TLOG_DEBUG(6) << "ResourceSetOR " << i->UID() << " contains " << i->get_contains().size() << " resources";
291 for (auto & i2 : i->get_contains()) {
292 if (!session.m_disabled_components.is_enabled(i2)) {
293 TLOG_DEBUG(6) << "disable resource-set-OR " << i->UID() << " because it's child " << i2 << " is disabled" ;
294 session.m_disabled_components.disable(*i);
295 session.m_disabled_components.disable_children(*i);
296 break;
297 }
298 }
299 }
300 }
301
302 TLOG_DEBUG(6) << "Session has " << rs_and.size() << " resourceSetANDs";
303 for (const auto& j : rs_and) {
304 if (session.m_disabled_components.is_enabled(j)) {
305 const std::vector<const ResourceBase*> &resources = j->get_contains();
306 TLOG_DEBUG(6) << "Checking " << resources.size() << " ResourceSetAND resources";
307 if (!resources.empty()) {
308 // check ANY child is enabled
309 bool found_enabled = false;
310 for (auto & j2 : resources) {
311 if (session.m_disabled_components.is_enabled(j2)) {
312 found_enabled = true;
313 TLOG_DEBUG(6) << "Found enabled resource " << j2->UID();
314 break;
315 }
316 }
317 if (found_enabled == false) {
318 TLOG_DEBUG(6) << "disable resource-set-AND " << j->UID() << " because all it's children are disabled" ;
319 session.m_disabled_components.disable(*j);
320 session.m_disabled_components.disable_children(*j);
321 }
322 }
323 }
324 }
325
326 if (session.m_disabled_components.size() == num) {
327 TLOG_DEBUG(6) << "after " << count << " iteration(s) auto-disabling algorithm found no newly disabled sets, exiting loop ..." ;
328 break;
329 }
330
331 unsigned int iLimit(1000);
332 if (count > iLimit) {
333 ers::error(ReadMaxAllowedIterations(ERS_HERE, iLimit));
334 break;
335 }
336 }
337 }
338 }
339
340 bool result(!session.m_disabled_components.is_enabled(this));
341 TLOG_DEBUG( 6) << "disabled(" << this << ") (UID=" << UID() << ") returns " << std::boolalpha << result ;
342 return result;
343}
344
345unsigned long
347{
348 return (session.m_disabled_components.m_num_of_slr_enabled_resources + session.m_disabled_components.m_num_of_slr_disabled_resources);
349}
#define ERS_DECLARE_ISSUE_BASE(namespace_name, class_name, base_class_name, message, base_attributes, attributes)
#define ERS_HERE
Represents database objects.
Defines base class for cache of template objects.
void remove_action(ConfigAction *ac)
void add_action(ConfigAction *ac)
const TARGET * cast() const noexcept
Casts object to different class.
bool disabled(const dunedaq::confmodel::Session &session) const
std::set< const std::string *, SortStringPtr > m_disabled
dunedaq::conffwk::Configuration & m_db
DisabledComponents(dunedaq::conffwk::Configuration &db, Session *session)
void load() noexcept
Call action on database file(s) load.
void unload() noexcept
Call action on database file(s) unload.
void disable_children(const dunedaq::confmodel::ResourceSet &)
std::set< const dunedaq::confmodel::Component * > m_user_enabled
void update(const dunedaq::conffwk::ConfigObject &obj, const std::string &name) noexcept
Call action on database object modification by user's code.
void notify(std::vector< dunedaq::conffwk::ConfigurationChange * > &) noexcept
Call action on database changes.
static unsigned long get_num_of_slr_resources(const dunedaq::confmodel::Session &p)
std::set< const dunedaq::confmodel::Component * > m_user_disabled
void disable(const dunedaq::confmodel::Component &c)
const std::vector< const dunedaq::confmodel::ResourceBase * > & get_contains() const
Get "contains" relationship value. A resource set is a container of resources to easily implement gro...
const std::vector< const dunedaq::confmodel::Segment * > & get_segments() const
Get "segments" relationship value. Nested list of Segments that form part of this Segment.
Definition Segment.hpp:114
const std::vector< const dunedaq::confmodel::Application * > & get_applications() const
Get "applications" relationship value. List of Applications that run in this Segment.
Definition Segment.hpp:141
void set_enabled(const std::set< const dunedaq::confmodel::Component * > &objs) const
void set_disabled(const std::vector< const dunedaq::confmodel::ResourceBase * > &value)
Set "disabled" relationship value. Resources that should not participate in the current run.
Definition Session.cpp:156
dunedaq::confmodel::DisabledComponents m_disabled_components
Definition Session.hpp:108
static void fill(const ResourceSet &rs, std::vector< const ResourceSetOR * > &rs_or, std::vector< const ResourceSetAND * > &rs_and, TestCircularDependency &cd_fuse)
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
Including Qt Headers.
AlgorithmError
Definition util.hpp:143
void error(const Issue &issue)
Definition ers.hpp:81