ATLAS Offline Software
ProxyProviderSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <algorithm>
6 #include <string>
7 #include <vector>
8 
9 #include "SGTools/DataProxy.h"
13 #include "AthenaKernel/BaseInfo.h"
14 
15 #include "GaudiKernel/IClassIDSvc.h"
16 #include "GaudiKernel/IConversionSvc.h"
17 #include "GaudiKernel/ListItem.h"
18 #include "GaudiKernel/GaudiException.h"
19 #include "GaudiKernel/ServiceHandle.h"
20 
21 #include "ProxyProviderSvc.h"
22 
23 #include "boost/range/adaptor/reversed.hpp"
24 #include "TClass.h"
25 
26 using namespace std;
27 
28 
29 namespace {
30 
31 
32 const SG::BaseInfoBase* getBaseInfo (CLID clid)
33 {
34  const SG::BaseInfoBase* bi = SG::BaseInfoBase::find (clid);
35  if (bi) return bi;
36 
37  // Try to force a dictionary load to get it defined.
38  ServiceHandle<IClassIDSvc> clidsvc ("ClassIDSvc", "ProxyProviderSvc");
39  if (!clidsvc.retrieve()) return nullptr;
40  std::string name;
41  if (!clidsvc->getTypeNameOfID (clid, name).isSuccess()) {
42  return nullptr;
43  }
44  (void)TClass::GetClass (name.c_str());
45  return SG::BaseInfoBase::find (clid);
46 }
47 
48 
49 } // anonyous namespace
50 
52  ISvcLocator* svcLoc):
53  base_class(name, svcLoc){
55 }
56 
58 
61 {
62  ATH_MSG_VERBOSE( "Initializing " << name() );
63 
64  const bool CREATEIF(true);
65  // cache pointer to Persistency Service
66  if (!(service("EventPersistencySvc", m_pDataLoader, CREATEIF)).isSuccess()) {
67  m_pDataLoader = 0;
68  ATH_MSG_ERROR("Could not get pointer to Persistency Service");
69  return StatusCode::FAILURE;
70  } else {
71 #ifdef DEBUGPPS
72  ATH_MSG_VERBOSE("Got pointer to Persistency Service " << m_pDataLoader);
73 #endif
74  }
75 
76  //get properties set;
77  if(!(AthService::initialize()).isSuccess()) {
78  return StatusCode::FAILURE;
79  }
80 
81  // Take care of any pending preLoadProxies requests.
84  }
85  m_pendingLoad.clear();
86 
87  return StatusCode::SUCCESS;
88 }
89 
90 
91 namespace {
92 
93 
95 void setProviderOnList (ProxyProviderSvc::TAdList& tList,
96  IAddressProvider* provider,
97  StoreID::type storeID)
98 {
99  for (SG::TransientAddress* tad : boost::adaptors::reverse (tList)) {
100  if (tad->provider() != nullptr) break;
101  tad->setProvider (provider, storeID);
102  }
103 }
104 
105 
106 } // anonymous namespace
107 
108 
109 StatusCode
111 {
112  if (m_providers.empty()) return StatusCode::SUCCESS;
113 
114  StoreID::type storeID = store.storeID();
115  TAdList tList;
116  for (IAddressProvider* provider : m_providers) {
117  ATH_CHECK( provider->preLoadAddresses(storeID, tList) );
118  setProviderOnList (tList, provider, storeID);
119  }
120  ATH_CHECK( addAddresses (store, tList) );
121  return StatusCode::SUCCESS;
122 }
123 
124 
127 StatusCode
129 {
130  // Due to initialization loops, it's possible for this to be called
131  // before the service is fully initialized. In that case, we may
132  // skip calling some of the providers. So we haven't been fully initialized,
133  // don't do anything now; rather, remember the store, and call
134  // preLoadProxies again for it at the end of initialize().
135  if (FSMState() == Gaudi::StateMachine::OFFLINE) {
136  m_pendingLoad.push_back (&store);
137  return StatusCode::SUCCESS;
138  }
139  return doPreLoadProxies (store);
140 }
141 
142 
145 StatusCode
147 {
148  if (m_providers.empty()) return StatusCode::SUCCESS;
149 
150  StoreID::type storeID = store.storeID();
151  TAdList tList;
152  for (IAddressProvider* provider : m_providers) {
153  ATH_CHECK( provider->loadAddresses(storeID, tList) );
154  setProviderOnList (tList, provider, storeID);
155  }
156  ATH_CHECK( addAddresses (store, tList) );
157  return StatusCode::SUCCESS;
158 }
159 
160 
167  TAdList& tList)
168 {
169  for (SG::TransientAddress* tad : tList) {
170  SG::DataProxy* proxy = store.proxy_exact(tad->clID(), tad->name());
173  if (0 != proxy)
174  {
175  proxy->setAddress(tad->address());
176  if (proxy->provider() == 0) {
177  proxy->setProvider(tad->provider(), store.storeID());
178  }
179  }
180  else {
181  if ( 0 == addAddress(store, std::move(*tad)) ) return StatusCode::FAILURE;
182  }
183  delete tad;
184  }
185 
186  return StatusCode::SUCCESS;
187 }
188 
189 
193  SG::TransientAddress&& tAddr)
194 {
195  //HACK! The proxies for all object those key starts with "HLTAutoKey" will be deleted at the end of each event (resetOnly=false)
196  //hence avoiding the proxy explosion observed with trigger object for releases <= 14.1.0
197  bool resetOnly(tAddr.name().substr(0,10) != std::string("HLTAutoKey"));
198  // std::cout << "PPS:addAdress: proxy for key " << tAddr->name() << " has resetOnly " << resetOnly << std::endl;
199  SG::DataProxy* dp = new SG::DataProxy(std::move(tAddr),
200  m_pDataLoader, true, resetOnly );
201 
202  // Must add the primary CLID first.
203  bool addedProxy = store.addToStore(dp->clID(), dp).isSuccess();
204  // ATH_MSG_VERBOSE("created proxy for " << tAddr->clID() << "/" << tAddr->name() << "using " << m_pDataLoader->repSvcType());
205  if (!addedProxy) {
206  ATH_MSG_ERROR ("Failed to add proxy to store "
207  << dp->clID() << "/" << dp->name());
208  delete dp;
209  dp = nullptr;
210  }
211  else {
212  // loop over all the transient CLIDs:
213  SG::TransientAddress::TransientClidSet tClid = dp->transientID();
214  for (CLID clid : tClid) {
215  if (clid != dp->clID()) {
216  bool flag = (store.addToStore(clid, dp)).isSuccess();
217  if (!flag) {
218  ATH_MSG_ERROR ("Failed to add proxy to store for symlink "
219  << clid << "/" << dp->name());
220  }
221  addedProxy &= flag;
222  }
223  }
224 
225  // loop over all alias'
226  for (const std::string& alias : dp->alias()) {
227  (store.addAlias(alias, dp)).ignore();
228  }
229 
230  // Add any other allowable conversions.
231  const SG::BaseInfoBase* bi = getBaseInfo (dp->clID());
232  if (bi) {
233  for (CLID clid : bi->get_bases()) {
234  if (std::find (tClid.begin(), tClid.end(), clid) == tClid.end()) {
235  store.addToStore (clid, dp).ignore();
236  dp->setTransientID (clid);
237  }
238  }
239 
240  for (CLID clid : bi->get_copy_conversions()) {
241  if (std::find (tClid.begin(), tClid.end(), clid) == tClid.end()) {
242  store.addToStore (clid, dp).ignore();
243  dp->setTransientID (clid);
244  }
245  }
246  }
247  }
248 
249  return dp;
250 }
251 
256 ProxyProviderSvc::retrieveProxy(const CLID& id, const std::string& key,
258 {
259  if ( !m_providers.empty() ) {
260  const EventContext& ctx = contextFromStore (store);
261  SG::TransientAddress pTAd (id, key);
262  pAPiterator iProvider(m_providers.begin()), iEnd(m_providers.end());
263  for (; iProvider != iEnd; ++iProvider) {
264  if ( ((*iProvider)->updateAddress(store.storeID(),&pTAd,ctx)).isSuccess() )
265  {
266  pTAd.setProvider(*iProvider, store.storeID());
267  return this->addAddress(store,std::move(pTAd));
268  }
269  }
270  }
271 
272  return nullptr;
273 }
274 
283 {
285  "EventContext");
286  if (proxy) {
287  EventContext* ctx = SG::DataProxy_cast<EventContext> (proxy);
288  if (ctx) return *ctx;
289  }
290  static const EventContext emptyContext;
291  return emptyContext;
292 }
293 
294 
295 void
296 ProxyProviderSvc::providerNamesPropertyHandler( Gaudi::Details::PropertyBase& /*theProp*/ ) {
297  //add declared providers to the list;
298  std::vector<std::string> providerNames = m_providerNames.value();
299 
300  // FIXME: AddressRemappingSvc needs to come at the end, if it's provided.
301  auto it = std::find (providerNames.begin(), providerNames.end(),
302  "AddressRemappingSvc");
303  if (it != providerNames.end() && it != providerNames.end()-1) {
304  providerNames.erase (it);
305  providerNames.push_back ("AddressRemappingSvc");
306  }
307 
308  for (const std::string& pName : providerNames) {
309  IService *pIS(0);
310  IAddressProvider *pAP(0);
311  ListItem tn(pName);
312  if (!(service(tn.type(), tn.name(), pIS)).isSuccess() ||
313  0 == (pAP = dynamic_cast<IAddressProvider*>(pIS))) {
314  ATH_MSG_ERROR(" getting Address Provider "<< pName);
315  throw GaudiException("Failed to locate address provider",
316  "ProxyProviderSvc::providerNamesPropertyHandle",
317  StatusCode::FAILURE);
318 
319  } else {
320  ATH_MSG_DEBUG(" added Address Provider "<< pIS->name());
321  }
323  }
324 
325 }
326 
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
ProxyProviderSvc::pAPiterator
std::list< IAddressProvider * >::iterator pAPiterator
Definition: ProxyProviderSvc.h:45
TileDCSDataPlotter.dp
dp
Definition: TileDCSDataPlotter.py:840
checkxAOD.ds
ds
Definition: Tools/PyUtils/bin/checkxAOD.py:257
ProxyProviderSvc::ProxyProviderSvc
ProxyProviderSvc(const std::string &name, ISvcLocator *svcLoc)
Standard Service Constructor.
Definition: ProxyProviderSvc.cxx:51
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:392
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
IProxyRegistry
a proxy registry (a read/write dictionary)
Definition: IProxyRegistry.h:27
ProxyProviderSvc::addProvider
virtual void addProvider(IAddressProvider *aProvider) override final
IAddressProvider manager functionality add a provider to the set of known ones.
Definition: ProxyProviderSvc.h:120
IProxyRegistry.h
initialize
void initialize()
Definition: run_EoverP.cxx:894
ProxyProviderSvc::m_pendingLoad
std::vector< IProxyRegistry * > m_pendingLoad
List of pending stores on which to run preLoadProxies().
Definition: ProxyProviderSvc.h:116
skel.it
it
Definition: skel.GENtoEVGEN.py:423
ProxyProviderSvc::doPreLoadProxies
StatusCode doPreLoadProxies(IProxyRegistry &storeToModify)
Definition: ProxyProviderSvc.cxx:110
SG::TransientAddress
Definition: TransientAddress.h:32
AthTPCnvSvc_test.clidsvc
clidsvc
Definition: AthTPCnvSvc_test.py:10
ProxyProviderSvc::m_providerNames
StringArrayProperty m_providerNames
property: the services declared as providers
Definition: ProxyProviderSvc.h:103
SG::TransientAddress::TransientClidSet
std::vector< CLID > TransientClidSet
Strictly a set, but there shouldn't be more than a handful of entries, so store it as a sorted vector...
Definition: TransientAddress.h:38
ProxyProviderSvc::initialize
virtual StatusCode initialize() override
Service boilerplate.
Definition: ProxyProviderSvc.cxx:60
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ProxyProviderSvc::addAddresses
StatusCode addAddresses(IProxyRegistry &store, TAdList &tList)
Add lists of TADs to the store.
Definition: ProxyProviderSvc.cxx:166
SG::BaseInfoBase::get_bases
const std::vector< CLID > & get_bases() const
Return the class IDs of all known bases of T (that have class IDs).
Definition: BaseInfo.cxx:304
python.DomainsRegistry.reg
reg
globals -----------------------------------------------------------------—
Definition: DomainsRegistry.py:343
IAddressProvider::loadAddresses
virtual StatusCode loadAddresses(StoreID::type, tadList &)
get all new addresses from Provider for this Event.
Definition: IAddressProvider.h:42
EventContextClid.h
Assign a CLID to EventContext.
ProxyProviderSvc::loadProxies
virtual StatusCode loadProxies(IProxyRegistry &storeToModify) override
add proxies to the store to modify (during Begin Event)
Definition: ProxyProviderSvc.cxx:146
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
ProxyProviderSvc::addAddress
SG::DataProxy * addAddress(IProxyRegistry &storeToModify, SG::TransientAddress &&tad)
create a new Proxy, overriding CLID and/or key
Definition: ProxyProviderSvc.cxx:192
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:54
ProxyProviderSvc.h
manages the address providers and add proxies on demand to the store
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ProxyProviderSvc::m_providers
std::list< IAddressProvider * > m_providers
the providers we know about. WE DON'T OWN THEM
Definition: ProxyProviderSvc.h:111
BaseInfo.h
Provide an interface for finding inheritance information at run time.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
COOLRates.alias
alias
Definition: COOLRates.py:1172
master.flag
bool flag
Definition: master.py:29
ClassID_traits
Default, invalid implementation of ClassID_traits.
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:40
IAddressProvider
interface for IOA providers
Definition: IAddressProvider.h:28
SG::BaseInfoBase::get_copy_conversions
std::vector< CLID > get_copy_conversions() const
Return known copy conversions.
Definition: BaseInfo.cxx:455
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
ProxyProviderSvc::retrieveProxy
virtual SG::DataProxy * retrieveProxy(const CLID &id, const std::string &key, IProxyRegistry &storeToModify) override
Use a provider to create a proxy for ID/KEY.
Definition: ProxyProviderSvc.cxx:256
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
SG::TransientAddress::setProvider
void setProvider(IAddressProvider *provider, StoreID::type storeID)
Definition: TransientAddress.h:317
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
SG::BaseInfoBase::find
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition: BaseInfo.cxx:569
ProxyProviderSvc::preLoadProxies
virtual StatusCode preLoadProxies(IProxyRegistry &storeToModify) override
IProxyProvider interface.
Definition: ProxyProviderSvc.cxx:128
ProxyProviderSvc::TAdList
std::list< SG::TransientAddress * > TAdList
Definition: ProxyProviderSvc.h:46
ProxyProviderSvc::m_pDataLoader
IConversionSvc * m_pDataLoader
Persistency Service.
Definition: ProxyProviderSvc.h:113
StoreID::type
type
Definition: StoreID.h:24
SG::BaseInfoBase
The non-template portion of the BaseInfo implementation.
Definition: Control/AthenaKernel/AthenaKernel/BaseInfo.h:451
ProxyProviderSvc::contextFromStore
const EventContext & contextFromStore(IProxyRegistry &ds) const
Retrieve the EventContext saved in store DS.
Definition: ProxyProviderSvc.cxx:282
IAddressProvider.h
IAddressProvider::preLoadAddresses
virtual StatusCode preLoadAddresses(StoreID::type, tadList &)
get all addresses from Provider : Called before Begin Event
Definition: IAddressProvider.h:36
SG::DataProxy
Definition: DataProxy.h:44
ProxyProviderSvc::~ProxyProviderSvc
virtual ~ProxyProviderSvc()
Definition: ProxyProviderSvc.cxx:57
ProxyProviderSvc::providerNamesPropertyHandler
void providerNamesPropertyHandler(Gaudi::Details::PropertyBase &theProp)
the handler for m_providerNames
Definition: ProxyProviderSvc.cxx:296
ServiceHandle< IClassIDSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
DataProxy.h