ATLAS Offline Software
Loading...
Searching...
No Matches
IOVSvcTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "IOVSvcTool.h"
6/*****************************************************************************
7 *
8 * IOVSvcTool.cxx
9 * IOVSvc
10 *
11 * Author: Charles Leggett
12 *
13 * Tool to provide automatic updating and callbacks for time dependent data
14 *
15 *****************************************************************************/
16
17
18#include "GaudiKernel/ISvcLocator.h"
19#include "GaudiKernel/IIncidentSvc.h"
20#include "GaudiKernel/Incident.h"
21#include "GaudiKernel/IAlgTool.h"
22#include "GaudiKernel/IToolSvc.h"
23#include "GaudiKernel/IClassIDSvc.h"
24#include "GaudiKernel/Guards.h"
25#include "GaudiKernel/ConcurrencyFlags.h"
26
33#include "SGTools/DataProxy.h"
35
36#include "IOVEntry.h"
37#include "IOVSvc/IOVAddress.h"
38
39#include <algorithm>
40#include <stdint.h>
41#include <cctype>
42#include <stdexcept>
43
44
45namespace {
46 std::atomic<bool> s_firstRun(true);
47}
48
49
50//
52//
53
54bool
56 if (a&&b) {
57 if (a->name()!=b->name()) return a->name()<b->name();
58 if (a->clID()!=b->clID()) return a->clID()<b->clID();
59 }
60 //Fall back to ptr comp (in principle random, but similar name and
61 //clid means that the path in COOL is likely to be similar):
62 return a<b;
63}
64
65//
67//
68
69
70IOVSvcTool::IOVSvcTool(const std::string& type, const std::string& name,
71 const IInterface* parent):
72 base_class( type, name, parent ),
73 m_storeName("StoreGateSvc"),
74 p_cndSvc("DetectorStore",name),
75 p_incSvc("IncidentSvc",name), p_PPSvc("ProxyProviderSvc",name),
76 p_CLIDSvc("ClassIDSvc",name), p_toolSvc("ToolSvc",name)
77{
78}
79
80/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
81
82StatusCode
84
85 SmartIF<IProperty> iovSvcProp{service("IOVSvc")};
86 ATH_CHECK( iovSvcProp.isValid() );
87
88 ATH_CHECK( setProperty( iovSvcProp->getProperty("preLoadRanges") ) );
89 ATH_CHECK( setProperty( iovSvcProp->getProperty("preLoadData") ) );
90 ATH_CHECK( setProperty( iovSvcProp->getProperty("partialPreLoadData") ) );
91 ATH_CHECK( setProperty( iovSvcProp->getProperty("preLoadExtensibleFolders") ) );
92 ATH_CHECK( setProperty( iovSvcProp->getProperty("updateInterval") ) );
93 ATH_CHECK( setProperty( iovSvcProp->getProperty("sortKeys") ) );
94 ATH_CHECK( setProperty( iovSvcProp->getProperty("forceResetAtBeginRun") ) );
95 ATH_CHECK( setProperty( iovSvcProp->getProperty("OutputLevel") ) );
96
97 int pri=100;
98
99 // Convert to uppercase
100 std::string updi = m_updateInterval;
101 std::transform(updi.begin(), updi.end(), updi.begin(),
102 [](unsigned char c) { return std::toupper(c); });
103
104 if (updi== "JOB") {
105 m_checkOnce = true;
106 m_checkTrigger = "BeginRun";
107 p_incSvc->addListener( this, "BeginRun", pri, true);
108 msg() << MSG::INFO;
109 msg().setColor(MSG::GREEN);
110 msg() << "IOVRanges will be checked only ";
111 msg().setColor(MSG::CYAN);
112 msg() << "once";
113 msg().setColor(MSG::GREEN);
114 msg() << " at the start of the job" << endmsg;
115 } else if (updi == "RUN") {
116 m_checkTrigger = "BeginRun";
117 p_incSvc->addListener( this, "BeginRun", pri, true);
118 msg() << MSG::INFO;
119 msg().setColor(MSG::GREEN);
120 msg() << "IOVRanges will be checked at every ";
121 msg().setColor(MSG::CYAN);
122 msg() << "Run" << endmsg;
123 } else if (updi == "EVENT") {
124 m_checkTrigger = "BeginEvent";
125 p_incSvc->addListener( this, "BeginEvent", pri, true);
126 p_incSvc->addListener( this, "BeginRun", pri, true);
127 msg() << MSG::INFO;
128 msg().setColor(MSG::GREEN);
129 msg() << "IOVRanges will be checked at every ";
130 msg().setColor(MSG::CYAN);
131 msg() << "Event" << endmsg;
132 } else {
133 ATH_MSG_FATAL("jobOption \"updateInterval\" must be one of "
134 << "\"event\" \"run\" or \"job\"");
135 return StatusCode::FAILURE;
136 }
137
138 if (m_preLoadData) {
139 msg() << MSG::INFO;
140 msg().setColor(MSG::GREEN);
141 msg() << "IOV Data will be preloaded at the same interval" << endmsg;
142 }
143
144 ATH_MSG_DEBUG("Tool initialized");
145
146 return StatusCode::SUCCESS;
147}
148
149
150/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
151
152void
153IOVSvcTool::handle(const Incident &inc) {
154
155 bool initial_first = m_first;
156
157 // Don't bother doing anything if we're handled the first run, and
158 // preLoadData has been set, or if we only want to check once at the
159 // beginning of the job
160 if (!initial_first && m_preLoadData && m_checkOnce) {
161 return;
162 }
163 else if (!initial_first) {
164 if ( inc.type() != m_checkTrigger && inc.type() != IncidentType::BeginRun ) {
165 return;
166 }
167 }
168
169 std::scoped_lock lock(m_handleMutex);
170 if (initial_first) {
171 if (!m_first && m_preLoadData && m_checkOnce) {
172 return;
173 }
174 // cppcheck-suppress oppositeInnerCondition
175 else if (!m_first) {
176 if ( inc.type() != m_checkTrigger && inc.type() != IncidentType::BeginRun ) {
177 return;
178 }
179 }
180 // cppcheck-suppress identicalInnerCondition
181 if (m_first) {
182 for (const auto& e : m_ignoredProxyNames) {
183 SG::DataProxy* proxy = p_cndSvc->proxy(e.first,e.second);
184 ATH_MSG_DEBUG("retrieving "<<fullProxyName(e.first,e.second));
185 if (proxy == nullptr) {
186 ATH_MSG_ERROR("ignoreProxy: could not retrieve proxy "
187 << fullProxyName(e.first,e.second) << " from store");
188 } else {
189 ignoreProxy( proxy );
190 ATH_MSG_DEBUG("will ignore resetting proxy " << fullProxyName(proxy));
191 }
192 }
193 m_first = false;
194 }
195 else {
196 initial_first=false;
197 }
198 }//end first
199 const bool first = initial_first;
200
201 // Forcing IOV checks on the first event in the run for AthenaMP (ATEAM-439)
202 if(Gaudi::Concurrency::ConcurrencyFlags::numProcs()==0) {
203 if (inc.type() == IncidentType::BeginRun) {
204 m_firstEventOfRun = true;
205 }
206
207 if (inc.type() == IncidentType::BeginEvent && m_firstEventOfRun) {
208 m_firstEventOfRun = false;
209 if (m_checkTrigger == "BeginEvent") {
210 return;
211 }
212 }
213 }
214
215 std::set< SG::DataProxy*, SortDPptr > proxiesToReset;
216 if ( inc.type() == m_checkTrigger || inc.type() == IncidentType::BeginRun ) {
217
218 const EventIDBase& eventID = inc.context().eventID();
219 const uint32_t event = eventID.lumi_block();
220 const uint32_t run = eventID.run_number();
221
222 ATH_MSG_DEBUG("Got event info: " << "run="<< run << ", event=" << event);
223
224 IOVTime curTime;
225 curTime.setRunEvent(run,event);
226 // get ns timestamp from event
227 curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset());
228
229 if (msgLvl(MSG::DEBUG)) {
230 msg().setColor(MSG::YELLOW,MSG::RED);
231 msg() << inc.type() << ": [R/LB] = " << curTime << endmsg;
232 }
233
234 if (inc.type() == IncidentType::BeginRun) {
235 // Signal BeginRun directly to IOVDbSvc
236 SmartIF<IIOVDbSvc> iovDB{service("IOVDbSvc", false)};
237 if (!iovDB) {
238 ATH_MSG_DEBUG("Unable to get the IOVDbSvc");
239 return;
240 }
241 if (StatusCode::SUCCESS != iovDB->signalBeginRun(curTime,
242 inc.context()))
243 {
244 ATH_MSG_ERROR("Unable to signal begin run to IOVDbSvc");
245 return;
246 }
247 else {
248 ATH_MSG_DEBUG("Signaled begin run to IOVDbSvc " << curTime);
249 }
250 }
251
252 if (first) {
253
254 for (const auto& tad : m_preLoad) {
255 StatusCode sc = regProxy(tad->clID(), tad->name());
256 if (StatusCode::SUCCESS != sc) {
257 ATH_MSG_ERROR("handle: Could not register proxy for " <<
258 fullProxyName(tad->clID(), tad->name()));
259 return;
260 }
261 }
262
263 if (msgLvl(MSG::VERBOSE)) {
265 msg() << endmsg;
266 }
267
268 // preLoad the ranges and data if requested.
269 if (preLoadProxies(inc.context()).isFailure()) {
270 ATH_MSG_ERROR("Problems preloading IOVRanges");
271 throw( std::runtime_error("IOVSvcTool::preLoadProxies") );
272 }
273
274 // Signal EndProxyPreload directly to IOVDbSvc
275 SmartIF<IIOVDbSvc> iovDB{service("IOVDbSvc", false)};
276 if (iovDB) {
277 iovDB->signalEndProxyPreload();
278 ATH_MSG_DEBUG("Signaled end proxy preload to IOVDbSvc " << curTime);
279 }
280 }// end if first
281
282 // If preLoadData has been set, never check validity of data again.
283 if (m_preLoadData && m_checkOnce) {
284 return;
285 }
286
287 // Otherwise, do the normal check for validity
288
289
290 if (msgLvl(MSG::DEBUG)) {
292 PrintStopSet();
293 msg() << endmsg;
294 }
295
296 //
299 //
300
301 if (inc.type() == IncidentType::BeginRun && m_forceReset && !s_firstRun) {
302
303 ATH_MSG_DEBUG("Resetting all proxies on BeginRun incident for store \""
304 << m_storeName << "\"");
305
306 if (msgLvl(MSG::VERBOSE)) {
307 for (SG::DataProxy* p : m_proxies) {
308 msg() << " " << m_names.at(p) << std::endl;
309 }
310 msg() << endmsg;
311 }
312 proxiesToReset = m_proxies;
313 } else {
314 scanStartSet(m_startSet_Clock,"(ClockTime)",proxiesToReset,curTime);
315 scanStartSet(m_startSet_RE,"(R/E)",proxiesToReset,curTime);
316
317 scanStopSet(m_stopSet_Clock,"(ClockTime)",proxiesToReset,curTime);
318 scanStopSet(m_stopSet_RE,"(R/E)",proxiesToReset,curTime);
319 }
320
322 auto itr = proxiesToReset.find(p);
323 if (itr != proxiesToReset.end()) {
324 proxiesToReset.erase( itr );
325 }
326 }
327
328 // If MT, must not call any callback functions after first event
329 if (!first && !proxiesToReset.empty() &&
330 ( (Gaudi::Concurrency::ConcurrencyFlags::numThreads() +
331 Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents()) > 0 ) ) {
332 ATH_MSG_FATAL("Cannot update Conditions via callback functions in MT after the first event");
333 for (const SG::DataProxy* prox : proxiesToReset) {
334 ATH_MSG_FATAL("CLID=" << prox->clID() << ", name=" << prox->name());
335 }
336 throw GaudiException("Cannot update Conditions via callback functions in MT after the first event",name(),StatusCode::FAILURE);
337 }
338
339 //
342 //
343 for (SG::DataProxy* prx : proxiesToReset) {
344 ATH_MSG_VERBOSE("clearing proxy payload for " << m_names.at(prx));
345
346 // Reset proxy
347
348 p_cndSvc->clearProxyPayload( prx );
349
350 // Load data if preload requested.
351
352 if ( (m_partialPreLoadData &&
353 m_partPreLoad.contains(TADkey(*prx)) )
354 ||
355 m_preLoadData ) {
356 ATH_MSG_VERBOSE("preloading data");
357
358 Gaudi::Guards::AuditorGuard auditor(m_names.at(prx), auditorSvc(), "preLoadProxy");
359 if (prx->accessData() == nullptr) {
360 ATH_MSG_ERROR("problems preloading data for " << m_names.at(prx));
361 }
362 }
363
364 }
365
367 for (SG::DataProxy* prx : proxiesToReset) {
368 const auto pitr = m_entries.find( prx );
369 if ( pitr != m_entries.end() && pitr->second->range()->isInRange(curTime) ) {
370 ATH_MSG_VERBOSE("range still valid for " << m_names.at(prx));
371 } else {
372 ATH_MSG_DEBUG("calling provider()->udpateAddress(TAD) for " << m_names.at(prx) );
373 if (!prx->updateAddress()) {
374 ATH_MSG_ERROR("handle: Could not update address");
375 return;
376 }
377 }
378
379 if (msgLvl(MSG::VERBOSE)) {
380 IOpaqueAddress *ioa = prx->address();
381 // Print out some debug info if this is an IOVAddress (coming
382 // from IOVASCIIDbSvc)
383 IOVAddress *iova = dynamic_cast<IOVAddress*>(ioa);
384 if (iova != nullptr) {
385 ATH_MSG_VERBOSE(" range: " << iova->range());
386 }
387 }
388
389 }
390
391 } // end if(inc.type() == m_checkTrigger)
392
393 if ( inc.type() == IncidentType::BeginRun) {
394 s_firstRun = false;
395 }
396
397}
398
399/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
400
404StatusCode
405IOVSvcTool::regProxy( SG::DataProxy *proxy, const std::string& key) {
406
407
408 if (proxy == nullptr) {
409 ATH_MSG_ERROR("proxy == 0");
410 return StatusCode::FAILURE;
411 }
412
413 ATH_MSG_DEBUG("registering proxy " << fullProxyName(proxy) << " at " << proxy);
414
415 if (m_proxies.contains(proxy)) {
416 ATH_MSG_DEBUG("Proxy for " << fullProxyName(proxy)
417 << " already registered: " << proxy->name());
418 return StatusCode::SUCCESS;
419 }
420
421 std::string tname;
422 ATH_CHECK( p_CLIDSvc->getTypeNameOfID(proxy->clID(), tname) );
423
424 const std::string fullname = tname + "[" + key + "]";
425
426 m_proxies.insert( proxy );
427 m_names[ proxy ] = std::move(fullname);
428
429 return StatusCode::SUCCESS;
430
431}
432
433
434/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
435
439StatusCode
441
442
443 if (proxy == nullptr) {
444 ATH_MSG_ERROR("proxy == 0");
445 return StatusCode::FAILURE;
446 }
447
448 ATH_MSG_DEBUG("removing proxy " << fullProxyName(proxy) << " at " << proxy);
449
450 const auto itr = m_proxies.find(proxy);
451 if (itr == m_proxies.end()) {
452 ATH_MSG_DEBUG("Proxy for " << fullProxyName(proxy)
453 << " not registered: " << proxy->name());
454 return StatusCode::SUCCESS;
455 }
456
457 m_proxies.erase( itr );
458
459 return StatusCode::SUCCESS;
460
461}
462
463/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
464
465namespace {
466
469 template <class SET>
470 void removeFromSet (IOVEntry* ent, SET& set)
471 {
472 auto it = set.lower_bound(ent);
473 while (it != set.end() && !set.key_comp()(*it, ent) && !set.key_comp()(ent,*it)) {
474 if (*it == ent)
475 set.erase (it++);
476 else
477 ++it;
478 }
479 }
480
481
482} // anonymous namespace
483
484/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
485
489StatusCode
491 SG::DataProxy *pNew) {
492
493 std::scoped_lock lock(m_handleMutex);
494 assert(nullptr != pOld);
495 assert(nullptr != pNew);
496
497 ATH_MSG_DEBUG("replace proxy " << fullProxyName(pOld)
498 << " @" << pOld << " with " << fullProxyName(pNew)
499 << " @" << pNew);
500
501 //start with the proxy list
502 if (0 == m_proxies.erase(pOld)) {
503 ATH_MSG_DEBUG("unregProxy: original proxy "
504 << fullProxyName(pOld) << " not found. Will return now ");
505 return StatusCode::SUCCESS;
506 }
507 m_proxies.insert(pNew);
508 //new name (possibly identical to old)
509 m_names.erase(pOld);
510 std::string tname;
511 ATH_CHECK( p_CLIDSvc->getTypeNameOfID(pNew->clID(), tname) );
512
513 m_names[pNew]=tname + "[" + pNew->name() + "]";
514
515 if (pOld != pNew) {
516 const auto itr = m_entries.find(pOld);
517 if (itr != m_entries.end()) {
518 IOVEntry* ent = itr->second.get();
519 removeFromSet (ent, m_startSet_Clock);
520 removeFromSet (ent, m_startSet_RE);
521 removeFromSet (ent, m_stopSet_Clock);
522 removeFromSet (ent, m_stopSet_RE);
523
524 setRange_impl (pNew, *ent->range());
525 m_entries.erase (itr);
526 }
527 }
528
529 return StatusCode::SUCCESS;
530
531}
532/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
533
537StatusCode
538IOVSvcTool::regProxy( const CLID& clid, const std::string& key ) {
539
540 SG::DataProxy* proxy = p_cndSvc->proxy(clid,key);
541
542 if (proxy == nullptr) {
543 ATH_MSG_ERROR("regProxy could not retrieve proxy "
544 << fullProxyName(clid,key) << " from store");
545 return StatusCode::FAILURE;
546 }
547
548 return ( regProxy(proxy, key) );
549
550}
551
552/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
553
557StatusCode
558IOVSvcTool::deregProxy( const CLID& clid, const std::string& key ) {
559
560 SG::DataProxy* proxy = p_cndSvc->proxy(clid,key);
561
562 if (proxy == nullptr) {
563 ATH_MSG_ERROR("regProxy could not retrieve proxy "
564 << fullProxyName(clid,key) << " from store");
565 return StatusCode::FAILURE;
566 }
567
568 return ( deregProxy(proxy) );
569
570}
571
572/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
573
577StatusCode
579
580 // check to see if it's a duplicate in preLoad
581 if (m_preLoad.contains( tad_in )) {
582 ATH_MSG_WARNING("preLoadTAD: TransientAddress ("
583 << tad_in->clID() << "/" << tad_in->name()
584 << ") alread in preLoad set. Not inserting");
585 return StatusCode::SUCCESS;
586 }
587
588 // check to see if it's a duplicate in partPreLoad
589 if (m_partPreLoad.contains( TADkey(*tad_in) )) {
590 ATH_MSG_WARNING("preLoadTAD: TransientAddress ("
591 << tad_in->clID() << "/" << tad_in->name()
592 << ") alread in partPreLoad set. Not inserting");
593 return StatusCode::SUCCESS;
594 }
595
596 m_preLoad.insert( std::make_unique<SG::TransientAddress>(tad_in->clID(),tad_in->name()) );
597
598 return StatusCode::SUCCESS;
599}
600
601/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
602
606StatusCode
608
609 if (m_preLoad.contains(tad_in)) {
610 ATH_MSG_WARNING("preLoadDataTAD: TransientAddress "
611 << fullProxyName( tad_in )
612 << " alread in preLoad set. Not inserting");
613 return StatusCode::SUCCESS;
614 }
615
616 if (m_partPreLoad.contains(TADkey(*tad_in))) {
617 ATH_MSG_WARNING("preLoadDataTAD: TransientAddress "
618 << fullProxyName( tad_in )
619 << " alread in partPreLoad set. Not inserting");
620 return StatusCode::SUCCESS;
621 }
622
623 auto tad = std::make_unique<SG::TransientAddress>(tad_in->clID(),tad_in->name());
624 m_partPreLoad.insert( TADkey(*tad) );
625 m_preLoad.insert( std::move(tad) );
626
627 return StatusCode::SUCCESS;
628}
629
630/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
631
633{
634 if (iovr.start().isTimestamp()) {
637 } else {
640 }
641
642 auto range = std::make_unique<IOVRange>(iovr);
643
644 const auto itr = m_entries.find(proxy);
645 if ( itr != m_entries.end() ) {
646
647 const auto& ent = itr->second;
648
649 if (*ent->range() == iovr) {
650 ATH_MSG_DEBUG("Range has not changed. Returning");
651 return;
652 // is this true? still in the start and stop sets? FIXME
653 }
654
655 const auto sitr = ent->getStartITR();
656 if ( !ent->removedStart() ) {
657 p_startSet->erase( sitr );
658 }
659
660 const auto pitr = ent->getStopITR();
661 if ( !ent->removedStop() ) {
662 p_stopSet->erase( pitr );
663 }
664
665 }
666
667 ATH_MSG_DEBUG("adding to start and stop sets");
668 auto ent = std::make_unique<IOVEntry>(proxy, std::move(range));
669 ent->setStartITR( p_startSet->insert( ent.get() ) );
670 ent->setStopITR( p_stopSet->insert( ent.get() ) );
671 m_entries.insert_or_assign(proxy, std::move(ent));
672}
673
674
675StatusCode
676IOVSvcTool::setRange(const CLID& clid, const std::string& key,
677 IOVRange& iovr)
678{
679
680 ATH_MSG_DEBUG("setRange() for clid: " << clid << " key: " << key
681 << " in IOVrange:" << iovr);
682
683 if (!iovr.start().isValid() || !iovr.stop().isValid()) {
684 ATH_MSG_ERROR("IOVRange " << iovr << "is not valid. Start OK: "
685 << iovr.start().isValid() << " Stop OK: " << iovr.stop().isValid()
686 << " run/evt/time min/max "
687 << IOVTime::MINRUN << "/" << IOVTime::MAXRUN << " "
688 << IOVTime::MINEVENT << "/" << IOVTime::MAXEVENT << " "
689 << IOVTime::MINTIMESTAMP << "/" << IOVTime::MAXTIMESTAMP << " ");
690 return StatusCode::FAILURE;
691 }
692
693 SG::DataProxy* proxy = p_cndSvc->proxy(clid,key);
694
695 if (proxy == nullptr) {
696 ATH_MSG_ERROR("setRange: Could not locate proxy for " << fullProxyName(clid,key));
697 return StatusCode::FAILURE;
698 }
699
700 std::scoped_lock lock(m_handleMutex);
701 setRange_impl (proxy, iovr);
702 return StatusCode::SUCCESS;
703}
704/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
705
706StatusCode
707IOVSvcTool::getRange(const CLID& clid, const std::string& key,
708 IOVRange& iov) const {
709
710 SG::DataProxy* dp = p_cndSvc->proxy(clid,key);
711
712 std::scoped_lock lock(m_handleMutex);
713 const auto itr = m_entries.find(dp);
714 if (itr == m_entries.end()) {
715 return StatusCode::FAILURE;
716 }
717
718 iov = *(itr->second->range());
719
720 return StatusCode::SUCCESS;
721
722}
723
724/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
725
726StatusCode
727IOVSvcTool::getRangeFromDB(const CLID& clid, const std::string& key,
728 IOVRange& range, std::string &tag,
729 std::unique_ptr<IOpaqueAddress>& ioa,
730 const IOVTime& curTime) const {
731
732 if (curTime.isValid()) {
733 return getRangeFromDB(clid, key, curTime, range, tag, ioa);
734 } else {
735 ATH_MSG_ERROR("Current Event not defined");
736 return StatusCode::FAILURE;
737 }
738
739}
740
741/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
742
743StatusCode
744IOVSvcTool::getRangeFromDB(const CLID& clid, const std::string& key,
745 const IOVTime& time, IOVRange& range,
746 std::string& tag,
747 std::unique_ptr<IOpaqueAddress>& ioa) const {
748 StatusCode sc(StatusCode::FAILURE);
749 SG::DataProxy* dp = p_cndSvc->proxy(clid,key);
750 if (nullptr != dp) {
751 IIOVDbSvc *idb =
752 dynamic_cast<IIOVDbSvc*>(dp->provider());
753 if (idb != nullptr) {
754 sc = idb->getRange(clid, key, time, range, tag, ioa);
755 } else {
756 ATH_MSG_ERROR("Provider is not an IIOVDbSvc");
757 }
758 } else {
759 ATH_MSG_ERROR("No proxy found for clid " << clid << " key " << key);
760 }
761 return sc;
762}
763
764/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
765
766StatusCode
767IOVSvcTool::setRangeInDB(const CLID& clid, const std::string& key,
768 const IOVRange& range, const std::string &tag) {
769
770
771 if (!range.start().isValid() || !range.stop().isValid()) {
772 ATH_MSG_ERROR("IOVRange " << range << "is not valid.");
773 return StatusCode::FAILURE;
774 }
775
776 SG::DataProxy* dp = p_cndSvc->proxy(clid,key);
777
778 if (dp == nullptr) {
779 ATH_MSG_ERROR("no Proxy found for " << fullProxyName( clid, key ));
780 return StatusCode::FAILURE;
781 }
782
783 std::scoped_lock lock(m_handleMutex);
784 if (!m_entries.contains(dp)) {
785 ATH_MSG_WARNING(fullProxyName(clid,key) << " not registered with the IOVSvc");
786 }
787
788 IAddressProvider *iadp = dp->provider();
789 IIOVDbSvc *idb = dynamic_cast<IIOVDbSvc*>(iadp);
790
791 if (idb != nullptr) {
792 return idb->setRange(clid, key, range, tag);
793 } else {
794 ATH_MSG_ERROR("Provider is not an IIOVDbSvc");
795 return StatusCode::FAILURE;
796 }
797
798}
799
800/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
801
802StatusCode
803IOVSvcTool::preLoadProxies(const EventContext& /*ctx*/) {
804
805 ATH_MSG_DEBUG("preLoadProxies()");
806
807 StatusCode scr(StatusCode::SUCCESS);
808
809 SmartIF<IIOVDbSvc> iovDB{service("IOVDbSvc", false)};
810
811 for (SG::DataProxy* dp : m_proxies) {
812 Gaudi::Guards::AuditorGuard auditor(m_names[dp], auditorSvc(), "preLoadProxy");
813
814 if (msgLvl(MSG::VERBOSE)) {
815 msg().setColor(MSG::CYAN);
816 msg() << "loading proxy for CLID: " << dp->clID()
817 << " " << m_names[dp] << endmsg;
818 }
819
820 if (dp->provider() == nullptr) {
821 msg() << MSG::FATAL << "No provider found for proxy " << m_names[dp]
822 << ". It is probably not a conditions object" << std::endl;
823 msg() << "Proxy Map: ";
824 PrintProxyMap(dp);
825 msg() << endmsg;
826 scr = StatusCode::FAILURE;
827 return (scr);
828 }
829
830
831 StatusCode sc;
832 // preload IOVRanges if jobOption set
833 // This gets us to an IAddressProvider (eg IOVDbSvc)
834 if (m_preLoadRanges) {
835 ATH_MSG_VERBOSE("updating Range");
836 if (!dp->updateAddress())
837 sc = StatusCode::FAILURE;
838 }
839
840 if ( ( m_partialPreLoadData &&
841 m_partPreLoad.contains(TADkey(*dp)) )
842 || m_preLoadData ) {
843
844 IIOVDbSvc::KeyInfo kinfo;
845 if ( !m_preLoadExtensibleFolders && iovDB &&
846 iovDB->getKeyInfo(dp->name(), kinfo) && kinfo.extensible ) {
847 ATH_MSG_VERBOSE("not preloading data for extensible folder " << dp->name());
848 }
849 else {
850 ATH_MSG_VERBOSE("preloading data for ("
851 << dp->clID() << "/"
852 << dp->name() << ")");
853 if( dp->accessData() != nullptr ) {
854 sc = StatusCode::SUCCESS;
855 } else {
856 sc = StatusCode::FAILURE;
857 ATH_MSG_ERROR("preLoading proxies: accessData() failed for " <<
858 dp->clID() << "/" << dp->name() << ")");
859 }
860 }
861 }
862
863 if (sc.isFailure()) scr=sc;
864
865 }
866
867 if (scr.isFailure()) {
868 ATH_MSG_ERROR("Problems preLoading proxies");
869 return scr;
870 }
871
872 return scr;
873}
874
875/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
876
877void
879 std::string objname;
880
881 if (!m_startSet_Clock.empty()) {
882 msg() << std::endl << "ClockTime start set: " << std::endl;
883 for (const auto ent : m_startSet_Clock) {
884 objname = m_names.at( ent->proxy() );
885 msg() << " " << objname << " (" << ent->proxy() << ") "
886 << ent->range()->start() << std::endl;
887 }
888 msg() << std::endl;
889 }
890
891 if (!m_startSet_RE.empty()) {
892 msg() << "Run/Event start set: " << std::endl;
893 for (const auto ent : m_startSet_RE) {
894 objname = m_names.at( ent->proxy() );
895 msg() << " " << objname << " (" << ent->proxy() << ") "
896 << ent->range()->start() << std::endl;
897 }
898 }
899
900}
901
902/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
903
904void
906 std::string objname;
907
908 if (!m_stopSet_Clock.empty()) {
909 msg() << std::endl << "ClockTime stop set: " << std::endl;
910 for( const auto ent : m_stopSet_Clock ) {
911 objname = m_names.at(ent->proxy());
912 msg() << " " << objname << " (" << ent->proxy() << ") "
913 << ent->range()->stop() << std::endl;
914 }
915 msg() << std::endl;
916 }
917
918 if (!m_stopSet_RE.empty()) {
919 msg() << "Run/Event stop set: " << std::endl;
920 for( const auto ent : m_stopSet_RE ) {
921 objname = m_names.at(ent->proxy());
922 msg() << " " << objname << " (" << ent->proxy() << ") "
923 << ent->range()->stop() << std::endl;
924 }
925 }
926}
927
928/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
929
930void
932 msg() << std::endl;
933 msg() << "------------------------------ IOVSvc Proxy Map "
934 << "------------------------------" << std::endl;
935
936 for (SG::DataProxy* p : m_proxies) {
937 PrintProxyMap(p);
938 }
939 msg() << "----------------------------------------------------------"
940 << "---------------------" << std::endl;
941}
942
943/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
944
945void
947
948 auto it = m_names.find(dp);
949 msg() << " " << dp << " " << dp->clID() << " "
950 << (it == m_names.end() ? "???" : it->second) << std::endl;
951}
952
953
954/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
955
956void
958 std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
959 const IOVTime& curTime) const {
960
961 if (pSet.empty()) return;
962
963 if (msgLvl(MSG::DEBUG)) {
964 msg() << MSG::DEBUG << "--> scan for resets: start set: " << type << std::endl;
965 }
966
967 auto start_itr( pSet.begin() );
968 while ( start_itr != pSet.end() ) {
969
970 if ((*start_itr)->range()->start() > curTime) {
971 if (msgLvl(MSG::DEBUG)) {
972 msg() << "\t" << m_names.at((*start_itr)->proxy()) << ": "
973 << (*start_itr)->range()->start()<<" <- removed" << std::endl;
974 }
975 proxiesToReset.insert( (*start_itr)->proxy() );
976
977 (*start_itr)->setRemovedStart( true );
978 pSet.erase(start_itr++);
979
980 } else {
981 break;
982 }
983 }
984
985 if (msgLvl(MSG::DEBUG)) {
986 msg() << endmsg;
987 }
988
989}
990
991/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
992
993void
995 std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
996 const IOVTime& curTime) const {
997
998 if (pSet.empty()) return;
999 if (msgLvl(MSG::DEBUG)) {
1000 msg() << MSG::DEBUG << "--> scan for resets: stop set: " << type << std::endl;
1001 }
1002
1003 auto stop_itr(pSet.begin());
1004 while ( stop_itr != pSet.end() ) {
1005
1006 if ((*stop_itr)->range()->stop() <= curTime) {
1007 if (msgLvl(MSG::DEBUG)) {
1008 msg() << " " << m_names.at((*stop_itr)->proxy()) << ": "
1009 << (*stop_itr)->range()->stop()<< " -> removed" << std::endl;
1010 }
1011 proxiesToReset.insert( (*stop_itr)->proxy() );
1012
1013 (*stop_itr)->setRemovedStop( true );
1014 pSet.erase(stop_itr++);
1015
1016 } else {
1017 break;
1018 }
1019 }
1020 if (msgLvl(MSG::DEBUG)) {
1021 msg() << endmsg;
1022 }
1023
1024}
1025
1026/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1027
1028bool
1030
1031 return m_proxies.contains( proxy );
1032
1033}
1034
1035/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1036
1037bool
1038IOVSvcTool::holdsProxy( const CLID& clid, const std::string& key ) const {
1039
1040 SG::DataProxy* proxy = p_cndSvc->proxy(clid,key);
1041
1042 if (proxy == nullptr) {
1043 ATH_MSG_ERROR("holdsProxy: could not retrieve proxy "
1044 << fullProxyName(clid,key) << " from store");
1045 return false;
1046 }
1047
1048 return ( holdsProxy(proxy) );
1049
1050}
1051
1052/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1053
1054void
1056
1057 for (SG::DataProxy* prx : m_proxies) {
1058 ATH_MSG_VERBOSE("clearing proxy payload for " << m_names[prx]);
1059
1060 p_cndSvc->clearProxyPayload(prx);
1061 }
1062
1063}
1064
1065/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1066
1067std::string
1069
1070 return fullProxyName(tad->clID(), tad->name());
1071
1072}
1073
1074/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1075
1076std::string
1078 return fullProxyName(dp->clID(), dp->name());
1079}
1080
1081/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1082
1083std::string
1084IOVSvcTool::fullProxyName( const CLID& clid, const std::string& key ) const {
1085
1086 std::string fullname, tname;
1087 if (p_CLIDSvc->getTypeNameOfID( clid, tname ).isFailure()) {
1088 fullname = "[";
1089 fullname += std::to_string(clid);
1090 fullname += '/';
1091 fullname += key;
1092 fullname += ']';
1093 } else {
1094 fullname = "[";
1095 fullname += tname;
1096 fullname += ':';
1097 fullname += std::to_string(clid);
1098 fullname += '/';
1099 fullname += key;
1100 fullname += ']';
1101 }
1102
1103 return fullname;
1104}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
uint32_t CLID
The Class ID type.
Abstract interface to IOVDbSvc to access IOVRange and tag information.
Validity Range object.
static Double_t a
static Double_t sc
#define SET(n)
Definition MD5.cxx:147
void setProperty(columnar::PythonToolHandle &self, const std::string &key, nb::object value)
interface for IOA providers
Abstract interface to IOVDbSvc to access IOVRange and tag information.
Definition IIOVDbSvc.h:38
virtual IOVRange range() const
Retrieve IOVRange.
Definition IOVAddress.h:126
void setStopITR(StopSet_t::iterator itr)
Definition IOVEntry.h:72
StopSet_t::iterator getStopITR() const
Definition IOVEntry.h:75
std::multiset< IOVEntry *, IOVEntryStopCritereon > StopSet_t
Definition IOVEntry.h:52
StartSet_t::iterator getStartITR() const
Definition IOVEntry.h:74
bool removedStop() const
Definition IOVEntry.h:66
std::multiset< IOVEntry *, IOVEntryStartCritereon > StartSet_t
Definition IOVEntry.h:51
IOVRange * range()
Definition IOVEntry.h:58
void setStartITR(StartSet_t::iterator itr)
Definition IOVEntry.h:71
bool removedStart() const
Definition IOVEntry.h:65
SG::DataProxy * proxy()
Definition IOVEntry.h:62
Validity Range object.
Definition IOVRange.h:30
const IOVTime & stop() const
Definition IOVRange.h:39
const IOVTime & start() const
Definition IOVRange.h:38
bool m_checkOnce
Definition IOVSvcTool.h:197
virtual StatusCode regProxy(SG::DataProxy *proxy, const std::string &key) override
Register a DataProxy with the service.
void setRange_impl(SG::DataProxy *proxy, IOVRange &iovr)
Gaudi::Property< bool > m_forceReset
Definition IOVSvcTool.h:206
std::string fullProxyName(const SG::TransientAddress *) const
void scanStopSet(IOVEntry::StopSet_t &pSet, const std::string &type, std::set< SG::DataProxy *, SortDPptr > &proxiesToReset, const IOVTime &curTime) const
Gaudi::Property< bool > m_preLoadRanges
Definition IOVSvcTool.h:201
std::set< std::pair< CLID, std::string > > m_ignoredProxyNames
Definition IOVSvcTool.h:177
ServiceHandle< IClassIDSvc > p_CLIDSvc
Definition IOVSvcTool.h:160
void PrintStopSet() const
virtual StatusCode replaceProxy(SG::DataProxy *pOld, SG::DataProxy *pNew) override
replace a registered DataProxy with a new version
Gaudi::Property< bool > m_partialPreLoadData
Definition IOVSvcTool.h:203
IOVEntry::StartSet_t * p_startSet
Definition IOVSvcTool.h:181
IOVEntry::StopSet_t m_stopSet_RE
Definition IOVSvcTool.h:185
StatusCode preLoadProxies(const EventContext &ctx)
std::string m_storeName
Definition IOVSvcTool.h:155
virtual StatusCode setRangeInDB(const CLID &clid, const std::string &key, const IOVRange &range, const std::string &tag) override
virtual void resetAllProxies() override
std::set< TADkey_t > m_partPreLoad
Definition IOVSvcTool.h:194
virtual StatusCode preLoadTAD(const SG::TransientAddress *) override
add to a set of TADs that will be registered at start of first event
IOVSvcTool(const std::string &type, const std::string &name, const IInterface *parent)
std::map< const SG::DataProxy *, std::unique_ptr< IOVEntry > > m_entries
Definition IOVSvcTool.h:179
std::set< SG::DataProxy * > m_ignoredProxies
Definition IOVSvcTool.h:176
ServiceHandle< IProxyProviderSvc > p_PPSvc
Definition IOVSvcTool.h:159
void PrintStartSet() const
std::atomic< bool > m_first
Definition IOVSvcTool.h:196
Gaudi::Property< std::string > m_updateInterval
Definition IOVSvcTool.h:207
Gaudi::Property< bool > m_preLoadData
Definition IOVSvcTool.h:202
virtual void ignoreProxy(const CLID &clid, const std::string &key) override
Definition IOVSvcTool.h:138
void scanStartSet(IOVEntry::StartSet_t &pSet, const std::string &type, std::set< SG::DataProxy *, SortDPptr > &proxiesToReset, const IOVTime &curTime) const
IOVEntry::StopSet_t * p_stopSet
Definition IOVSvcTool.h:182
IOVEntry::StopSet_t m_stopSet_Clock
Definition IOVSvcTool.h:185
std::string m_checkTrigger
Definition IOVSvcTool.h:199
std::map< const SG::DataProxy *, std::string > m_names
Definition IOVSvcTool.h:163
virtual StatusCode initialize() override
TADkey_t TADkey(const SG::DataProxy &p)
Definition IOVSvcTool.h:190
std::set< std::unique_ptr< const SG::TransientAddress >, SortTADptr > m_preLoad
Definition IOVSvcTool.h:187
void PrintProxyMap() const
virtual StatusCode deregProxy(SG::DataProxy *proxy) override
Deregister a DataProxy with the service.
IOVEntry::StartSet_t m_startSet_RE
Definition IOVSvcTool.h:184
bool m_firstEventOfRun
Definition IOVSvcTool.h:198
Gaudi::Property< bool > m_preLoadExtensibleFolders
Definition IOVSvcTool.h:204
virtual StatusCode getRange(const CLID &clid, const std::string &key, IOVRange &iov) const override
virtual bool holdsProxy(SG::DataProxy *proxy) const override
ServiceHandle< IToolSvc > p_toolSvc
Definition IOVSvcTool.h:161
virtual StatusCode getRangeFromDB(const CLID &clid, const std::string &key, IOVRange &range, std::string &tag, std::unique_ptr< IOpaqueAddress > &ioa, const IOVTime &curTime) const override
virtual StatusCode preLoadDataTAD(const SG::TransientAddress *) override
add to a set of TADs that who's data will be preLoaded
IOVEntry::StartSet_t m_startSet_Clock
Definition IOVSvcTool.h:184
ServiceHandle< StoreGateSvc > p_cndSvc
Definition IOVSvcTool.h:157
virtual void handle(const Incident &) override
ServiceHandle< IIncidentSvc > p_incSvc
Definition IOVSvcTool.h:158
std::set< SG::DataProxy *, SortDPptr > m_proxies
Definition IOVSvcTool.h:174
virtual StatusCode setRange(const CLID &clid, const std::string &key, IOVRange &) override
Basic time unit for IOVSvc.
Definition IOVTime.h:33
static constexpr uint64_t MAXTIMESTAMP
Definition IOVTime.h:58
static constexpr uint32_t MAXRUN
Definition IOVTime.h:48
void setRunEvent(uint32_t run, uint32_t event) noexcept
Definition IOVTime.cxx:96
bool isValid() const noexcept
Definition IOVTime.cxx:117
static constexpr uint32_t MINEVENT
Definition IOVTime.h:50
static constexpr uint64_t MINTIMESTAMP
Definition IOVTime.h:56
void setTimestamp(uint64_t timestamp) noexcept
Definition IOVTime.cxx:72
static constexpr uint32_t MAXEVENT
Definition IOVTime.h:51
static constexpr uint32_t MINRUN
Definition IOVTime.h:44
bool isTimestamp() const noexcept
Definition IOVTime.h:111
CLID clID() const
Retrieve clid.
virtual const name_type & name() const override final
Retrieve data object key == string.
CLID clID() const
Retrieve string key:
const std::string & name() const
Get the primary (hashed) SG key.
STL class.
Filled by IIOVDbSvc::getKeyInfo.
Definition IIOVDbSvc.h:44
bool operator()(const SG::DataProxy *, const SG::DataProxy *) const
MsgStream & msg
Definition testRead.cxx:32
int run(int argc, char *argv[])