All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
RecordDataSvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RecordDataSvc.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : System ( The LHCb Offline System)
6 //
7 // Description: implementation of the Transient event data service.
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 10/12/08| Initial version | MF
15 // +---------+----------------------------------------------+---------
16 //
17 //====================================================================
18 #define DATASVC_RECORDDATASVC_CPP
19 
20 #include "GaudiKernel/SmartIF.h"
21 #include "GaudiKernel/MsgStream.h"
22 #include "GaudiKernel/IProperty.h"
23 #include "GaudiKernel/DataObject.h"
24 #include "GaudiKernel/ISvcLocator.h"
25 #include "GaudiKernel/IIncidentSvc.h"
26 #include "GaudiKernel/IConversionSvc.h"
27 #include "GaudiKernel/IOpaqueAddress.h"
28 #include "GaudiKernel/DataIncident.h"
29 #include "GaudiKernel/RegistryEntry.h"
30 
31 #include "RecordDataSvc.h"
32 using namespace std;
33 
34 // Instantiation of a static factory class used by clients to create
35 // instances of this service
37 
40  // Nothing to do: just call base class initialisation
42  MsgStream log(msgSvc(),name());
43 
44  if ( !sc.isSuccess() ) { // Base class failure
45  return sc;
46  }
47  // Attach data loader facility
48  m_cnvSvc = service(m_persSvcName, true);
49  if ( !m_cnvSvc) {
50  log << MSG::ERROR << "Failed to access RecordPersistencySvc." << endmsg;
51  return StatusCode::FAILURE;
52  }
53  auto prp = m_cnvSvc.as<IProperty>();
54  if ( prp ) {
55  //prp->setProperty();
56  }
57  sc = setDataLoader( m_cnvSvc.get() );
58  if ( !sc.isSuccess() ) {
59  log << MSG::ERROR << "Failed to attach dataloader RecordPersistencySvc." << endmsg;
60  return sc;
61  }
62 
63  sc = setRoot(m_rootName, new DataObject());
64  if( !sc.isSuccess() ) {
65  log << MSG::WARNING << "Error declaring Record root DataObject" << endmsg;
66  return sc;
67  }
68 
69  if( !m_incidentSvc ) {
70  log << MSG::FATAL << "IncidentSvc is invalid--base class failed." << endmsg;
71  return sc;
72  }
73 
78  m_incidentSvc->addListener(this,"FILE_OPEN_READ");
79  m_incidentSvc->addListener(this,m_saveIncidentName);
80  return sc;
81 }
82 
85  if( m_incidentSvc ) m_incidentSvc->removeListener(this);
86  m_cnvSvc.reset();
88  return StatusCode::SUCCESS ;
89 }
90 
92 void RecordDataSvc::handle(const Incident& incident) {
93  if ( incident.type() == "FILE_OPEN_READ" ) {
95  auto inc = dynamic_cast<const Ctxt*>(&incident);
96  if ( !inc ) {
97  MsgStream log(msgSvc(),name());
98  log << MSG::ALWAYS << "Received invalid incident of type:" << incident.type() << endmsg;
99  } else {
100  registerRecord(inc->source(),inc->tag());
101  if ( !m_incidentName.empty() ) {
102  auto incidents = m_incidents;
103  m_incidents.clear();
104  for( const auto& i : incidents)
105  m_incidentSvc->fireIncident(Incident{i,m_incidentName});
106  }
107  }
108  } else if ( incident.type() == m_saveIncidentName ) {
109  MsgStream log(msgSvc(),name());
110  log << MSG::ALWAYS << "Saving records not implemented." << endmsg;
111  }
112 }
113 
116  MsgStream log(msgSvc(),name());
117  if ( !pObj ) {
118  log << MSG::ERROR << "Failed to load records object: " << pObj->identifier() << endmsg;
119  } else {
120  vector<IRegistry*> leaves;
121  DataObject* p = nullptr;
122  const string& id0 = pObj->identifier();
123  StatusCode sc = retrieveObject(id0, p);
124  if ( sc.isSuccess() ) {
125  log << MSG::DEBUG << "Loaded records object: " << id0 << endmsg;
126  sc = objectLeaves(pObj, leaves);
127  if ( sc.isSuccess() ) {
128  for ( const auto& i : leaves) loadRecords(i);
129  }
130  }
131  }
132 }
133 
135 void RecordDataSvc::registerRecord(const string& data, IOpaqueAddress* pAddr) {
136  if ( !data.empty() && pAddr ) {
137  MsgStream log(msgSvc(),name());
138  string fid = data;
139  log << MSG::DEBUG << "Request to load record for file " << fid << endmsg;
140  StatusCode sc = registerAddress(m_root,fid,pAddr);
141  if ( !sc.isSuccess() ) {
142  log << MSG::WARNING << "Failed to register record for:" << fid << endmsg;
143  pAddr->release();
144  return;
145  }
146  if ( m_autoLoad ) {
147  loadRecords(pAddr->registry());
148  }
149  m_incidents.push_back(pAddr->registry()->identifier());
150  }
151  else if ( !data.empty() && !pAddr ) {
152  MsgStream log(msgSvc(),name());
153  log << MSG::INFO << "Failed to register record for:" << data << " [Invalid Address]" << endmsg;
154  }
155 }
156 
159 : base_class(name,svc)
160 {
161  m_rootName = "/Records";
162  declareProperty("AutoLoad", m_autoLoad = true);
163  declareProperty("IncidentName", m_incidentName = "");
164  declareProperty("SaveIncident", m_saveIncidentName = "SAVE_RECORD");
165  declareProperty("PersistencySvc", m_persSvcName = "PersistencySvc/RecordPersistencySvc");
166 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode finalize() override
Service finalization.
std::string m_persSvcName
Property: name of the persistency service.
Definition: RecordDataSvc.h:54
def initialize()
Definition: AnalysisTest.py:12
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
const std::string & type() const
Access to the incident type.
Definition: Incident.h:34
std::string m_incidentName
Property: name of incident to be fired if new record arrives.
Definition: RecordDataSvc.h:50
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
bool m_autoLoad
Property: autoload of records (default: true)
Definition: RecordDataSvc.h:48
STL namespace.
virtual unsigned long release()=0
release reference to object
A RecordDataSvc is the base class for event services.
Definition: RecordDataSvc.h:25
std::string m_saveIncidentName
Property: name of the "save" incident.
Definition: RecordDataSvc.h:52
virtual IRegistry * registry() const =0
Update branch name.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
void clear(STATE_TYPE _i=std::ios_base::failbit)
Definition: MsgStream.h:222
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
StatusCode finalize() override
Service initialization.
Definition: DataSvc.cpp:1188
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
StatusCode initialize() override
Service initialization.
Definition: DataSvc.cpp:1153
Base class for all Incidents (computing events).
Definition: Incident.h:16
RecordDataSvc(const std::string &name, ISvcLocator *svc)
Standard Constructor.
virtual const id_type & identifier() const =0
Full identifier (or key)
void handle(const Incident &incident) override
IIncidentListener override: Inform that a new incident has occured.
void registerRecord(const std::string &data, IOpaqueAddress *pAddr)
Load new record into the data store if necessary.
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:108
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:21
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
list i
Definition: ana.py:128
void loadRecords(IRegistry *pReg)
Load dependent records into memory.