ATLAS Offline Software
Loading...
Searching...
No Matches
DBReplicaSvc Class Reference

#include <DBReplicaSvc.h>

Inheritance diagram for DBReplicaSvc:
Collaboration diagram for DBReplicaSvc:

Public Member Functions

virtual StatusCode initialize () override
void sort (std::vector< const coral::IDatabaseServiceDescription * > &replicaSet) override

Private Types

typedef std::pair< std::string, int > ServerPair

Private Member Functions

StatusCode readConfig ()

Private Attributes

Gaudi::Property< std::string > m_configfile {this, "ConfigFile", "dbreplica.config"}
Gaudi::Property< std::string > m_testhost {this, "TestHost", ""}
Gaudi::Property< std::string > m_coolsqlitepattern {this, "COOLSQLiteVetoPattern", ""}
Gaudi::Property< bool > m_usecoolsqlite {this, "UseCOOLSQLite", true}
Gaudi::Property< bool > m_usecoolfrontier {this, "UseCOOLFrontier", true}
Gaudi::Property< bool > m_usegeomsqlite {this, "UseGeomSQLite", true}
Gaudi::Property< bool > m_nofailover {this, "DisableFailover", false}
Gaudi::Property< int > m_retrialPeriod {this, "ConnectionRetrialPeriod", 300}
 ConnectionRetrialPeriod, retry period for CORAL Connection Service: default = 30 seconds.
Gaudi::Property< int > m_retrialTimeOut {this, "ConnectionRetrialTimeOut", 3600}
 ConnectionRetrialTimeOut, the retrial time out for CORAL Connection Service: default = 300 seconds.
Gaudi::Property< int > m_timeOut {this, "ConnectionTimeOut", 5}
 ConnectionTimeOut, the time out for CORAL Connection Service: default = 5 seconds.
Gaudi::Property< bool > m_connClean {this, "ConnectionCleanUp", false}
 ConnectionCleanUp - whether to use CORAL connection management thread: default = false.
Gaudi::Property< int > m_frontierComp {this, "FrontierCompression", 5}
 Frontier proprties, compression level and list of schemas to be refreshed: default = 5.
Gaudi::Property< std::vector< std::string > > m_frontierRefresh {this, "FrontierRefreshSchema", {}}
coral::Context * m_context {nullptr}
bool m_frontiergen {false}
std::string m_hostname
std::vector< ServerPairm_servermap

Detailed Description

Definition at line 18 of file DBReplicaSvc.h.

Member Typedef Documentation

◆ ServerPair

typedef std::pair<std::string, int> DBReplicaSvc::ServerPair
private

Definition at line 52 of file DBReplicaSvc.h.

Member Function Documentation

◆ initialize()

StatusCode DBReplicaSvc::initialize ( )
overridevirtual

Definition at line 21 of file DBReplicaSvc.cxx.

21 {
22
23 // determine the hostname (or override if from joboption)
25 // if nothing set on job-options, try environment variable ATLAS_CONDDB
26 if (m_hostname.empty()) {
27 const char* chost=getenv("ATLAS_CONDDB");
28 if (chost) m_hostname=chost;
29 }
30 // if ATLAS_CONDDB not set, try environment variable HOSTNAME
31 if (m_hostname.empty()) {
32 const char* chost=getenv("HOSTNAME");
33 if (chost) m_hostname=chost;
34 // check if the returned host has a .
35 if (m_hostname.find('.')==std::string::npos) {
36 ATH_MSG_DEBUG("HOSTNAME " << m_hostname
37 << " has no domain - try hostname --fqdn");
38 m_hostname="unknown";
39#ifndef __APPLE__
40 system("hostname --fqdn > hostnamelookup.tmp");
41#else
42 // Unfortunately Leopard doesn't understand the -f option to hostname, only Snow Leopard does
43 system("hostname > hostnamelookup.tmp");
44#endif
45 std::ifstream infile;
46 infile.open("hostnamelookup.tmp");
47 if (infile) {
49 ATH_MSG_DEBUG ("HOSTNAME from fqdn: " << m_hostname);
50 } else {
51 m_hostname="unknown";
52 }
53 }
54 }
55 // check if FRONTIER_SERVER is set, if so, allow generic replicas
56 const char* cfrontier=getenv("FRONTIER_SERVER");
57 if (m_usecoolfrontier && cfrontier && strcmp(cfrontier,"")!=0) {
58 ATH_MSG_INFO ("Frontier server at " << cfrontier
59 << " will be considered for COOL data");
60 m_frontiergen=true;
61 }
63 if (!m_usecoolsqlite) {
64 ATH_MSG_INFO ("COOL SQLite replicas will be excluded");
65 } else if (m_coolsqlitepattern!="") {
66 ATH_MSG_INFO ("COOL SQLite replicas will be excluded if matching pattern "
68 }
70 ATH_MSG_INFO ("COOL Frontier replicas will be excluded");
71 if (!m_usegeomsqlite)
72 ATH_MSG_INFO ("Geometry SQLite replicas will be excluded");
73 if (m_nofailover)
74 ATH_MSG_INFO ("Failover to secondary replicas disabled");
75 //Other coral configuration settting:
76
77 m_context = &coral::Context::instance();
78 if (m_context == nullptr) {
79 ATH_MSG_FATAL("Failed to access CORAL Context");
80 return (StatusCode::FAILURE);
81 }
82
83 coral::ConnectionService conSvcH;
84 coral::IConnectionServiceConfiguration& csConfig = conSvcH.configuration();
85 csConfig.setReplicaSortingAlgorithm(*this);
86 ATH_MSG_DEBUG("Successfully setup replica sorting algorithm");
87
88 csConfig.setConnectionRetrialPeriod(m_retrialPeriod);
89 csConfig.setConnectionRetrialTimeOut(m_retrialTimeOut);
90 if (m_connClean) {
91 csConfig.enablePoolAutomaticCleanUp();
92 csConfig.setConnectionTimeOut(m_timeOut);
93 } else {
94 csConfig.disablePoolAutomaticCleanUp();
95 csConfig.setConnectionTimeOut(0);
96 }
97 ATH_MSG_INFO("Set connectionsvc retry/timeout/IDLE timeout to " << m_retrialPeriod << "/" << m_retrialTimeOut << "/" << m_timeOut
98 << " seconds with connection cleanup "
99 << (csConfig.isPoolAutomaticCleanUpEnabled() ? "enabled" : "disabled"));
100 // set Frontier web cache compression level
101 coral::IWebCacheControl& webCache = conSvcH.webCacheControl();
102 webCache.setCompressionLevel(m_frontierComp);
103 ATH_MSG_INFO("Frontier compression level set to " << webCache.compressionLevel());
104
105 return sc;
106}
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
Gaudi::Property< int > m_retrialTimeOut
ConnectionRetrialTimeOut, the retrial time out for CORAL Connection Service: default = 300 seconds.
std::string m_hostname
Gaudi::Property< bool > m_connClean
ConnectionCleanUp - whether to use CORAL connection management thread: default = false.
Gaudi::Property< std::string > m_testhost
Gaudi::Property< bool > m_usegeomsqlite
coral::Context * m_context
Gaudi::Property< int > m_timeOut
ConnectionTimeOut, the time out for CORAL Connection Service: default = 5 seconds.
Gaudi::Property< int > m_frontierComp
Frontier proprties, compression level and list of schemas to be refreshed: default = 5.
Gaudi::Property< int > m_retrialPeriod
ConnectionRetrialPeriod, retry period for CORAL Connection Service: default = 30 seconds.
Gaudi::Property< bool > m_usecoolsqlite
Gaudi::Property< bool > m_nofailover
Gaudi::Property< std::string > m_coolsqlitepattern
StatusCode readConfig()
Gaudi::Property< bool > m_usecoolfrontier
::StatusCode StatusCode
StatusCode definition for legacy code.
std::string getenv(const std::string &variableName)
get an environment variable

◆ readConfig()

StatusCode DBReplicaSvc::readConfig ( )
private

Definition at line 108 of file DBReplicaSvc.cxx.

108 {
109
110 // try to locate the file using pathresolver
111 std::string file=PathResolver::find_file(m_configfile,"DATAPATH");
112 if (file.empty()) {
113 ATH_MSG_ERROR ("Cannot locate configuration file " << m_configfile);
114 return StatusCode::FAILURE;
115 }
116 // open and read the file
117 ATH_MSG_INFO ("Read replica configuration from " << file);
118 FILE* p_inp=fopen(file.c_str(),"r");
119 if (p_inp==nullptr) {
120 ATH_MSG_ERROR ("Cannot open configuration file");
121 return StatusCode::FAILURE;
122 }
123 // buffer for reading line
124 const unsigned int bufsize=999;
125 char p_buf[bufsize];
126 while (!feof(p_inp)) {
127 char* p_line=fgets(p_buf,bufsize,p_inp);
128 if (p_line!=NULL && p_line[0]!='#') {
129 std::string buf=std::string(p_line);
130 std::string::size_type iofs1=0;
131 // analyse based on spaces as separator
132 bool sequal=false;
133 std::vector<std::string> domains;
134 std::vector<std::string> servers;
135 while (iofs1<buf.size()) {
136 std::string::size_type iofs2=buf.find(' ',iofs1);
137 // allow for trailing linefeed
138 if (iofs2==std::string::npos) iofs2=buf.size()-1;
139 std::string token=buf.substr(iofs1,iofs2-iofs1);
140 // skip empty or space tokens
141 if (token!="" && token!=" ") {
142 if (token=="=") {
143 sequal=true;
144 } else if (!sequal) {
145 // token is a domain name
146 domains.push_back(std::move(token));
147 } else {
148 // token is a server name
149 if (!m_nofailover || servers.size()==0 || token=="atlas_dd")
150 servers.push_back(std::move(token));
151 }
152 }
153 iofs1=iofs2+1;
154 }
155 // check the list of domains against the hostname to see if this
156 // set of servers is appropriate
157 bool useit=false;
158 unsigned int bestlen=0;
159 for (const std::string& d : domains) {
160 std::string::size_type len=d.size();
161 std::string::size_type hlen=m_hostname.size();
162 if (hlen>=len && d==m_hostname.substr(hlen-len,len)) {
163 if (len>bestlen) {
164 useit=true;
165 bestlen=len;
166 }
167 }
168 // for 'default' domain name, add the servers as a last resort
169 // if nothing has been found so far
170 if ("default"==d && m_servermap.empty()) {
171 ATH_MSG_INFO ("No specific match for domain found - use default fallback");
172 useit=true;
173 bestlen=0;
174 }
175 }
176 if (useit) {
177 // assign these servers, priority based on position in list
178 // and length of match of domain name
179 for (unsigned int i=0;i<servers.size();++i) {
180 int priority=i*5-100*bestlen;
181 // only add ATLF Frontier generic servers if allowed
182 if (servers[i]!="ATLF" || m_frontiergen) {
183 // give generic Frontier server higher (more negative) priority
184 // so it will be preferred over DBRelaese SQLite file
185 if (servers[i]=="ATLF") priority-=2000;
186 m_servermap.push_back(ServerPair(servers[i],priority));
187 ATH_MSG_DEBUG ("Candidate server " << servers[i] <<
188 " (priority " << priority << ")");
189 }
190 }
191 }
192 }
193 }
194 fclose(p_inp);
195 msg() << MSG::INFO << "Total of " << m_servermap.size() <<
196 " servers found for host " << m_hostname << " [";
197 for (const auto& [name, pri] : m_servermap) {
198 msg() << name << " ";
199 }
200 msg() << "]" << endmsg;
201 return StatusCode::SUCCESS;
202}
#define endmsg
#define ATH_MSG_ERROR(x)
std::pair< std::string, int > ServerPair
std::vector< ServerPair > m_servermap
Gaudi::Property< std::string > m_configfile
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
MsgStream & msg
Definition testRead.cxx:32
TFile * file

◆ sort()

void DBReplicaSvc::sort ( std::vector< const coral::IDatabaseServiceDescription * > & replicaSet)
override

Definition at line 204 of file DBReplicaSvc.cxx.

204 {
205 // if only one replica offered, return immediately
206 // this helps for online, where explicit configuration file is given
207 // that does not match any of the standard dbreplica.config entries
208 if (replicaSet.size()<=1) return;
209
210 // loop through all the offered replicas
211 std::map<int,const coral::IDatabaseServiceDescription*> primap;
212 for (const coral::IDatabaseServiceDescription* dbdescr : replicaSet) {
213
214 const std::string conn=dbdescr->connectionString();
215 ATH_MSG_DEBUG ("Replica connection string: " << conn);
216 if (conn.find("sqlite_file")!=std::string::npos) {
217 // include SQLite files unless they are vetoed
218 // COOL SQLIte files recognised by ALLP in connection string
219 // vetoed if use-SQlite flag not set, or pattern is found in
220 // SQLite filename
221 // Geometry SQLite files recognised by geomDB in connection string
222 if (!( ((m_usecoolsqlite==false ||
223 (m_coolsqlitepattern!="" &&
224 conn.find(m_coolsqlitepattern)!=std::string::npos))
225 && conn.find("ALLP")!=std::string::npos)
226 || ((m_usegeomsqlite==false ||
227 (m_coolsqlitepattern!="" &&
228 conn.find(m_coolsqlitepattern)!=std::string::npos))
229 && conn.find("geomDB")!=std::string::npos))) {
230 // local sqlite files get -9999, DB release ones
231 // (identified with path starting / or containing DBRelease)
232 // get -999, so local one will be tried first if present
233 if (conn.find("sqlite_file:/")!=std::string::npos ||
234 conn.find("DBRelease")!=std::string::npos) {
235 primap[-999]=dbdescr;
236 } else {
237 primap[-9999]=dbdescr;
238 }
239 }
240 } else {
241 // define priority for technologies with this server (lower = better)
242 bool veto=false;
243 int spri=5; // default for Oracle
244 if (conn.find("frontier:")!=std::string::npos) {
245 spri=3; // use frontier before oracle
246 // dont use frontier servers if disabled, or generic Frontier server
247 // is specified (via '()' in server definition) and FRONTIER_SERVER
248 // env variable is not set
249 if (!m_usecoolfrontier ||
250 (conn.find("()")!=std::string::npos && m_frontiergen==false))
251 veto=true;
252 }
253 // extract the server name (assuming URLs "techno://server/schema")
254 std::string::size_type ipos1=conn.find("://");
255 std::string::size_type ipos2=conn.find('/',ipos1+3);
256 // for Frontier, have to remove the (..) part after the server name
257 // e.g. frontier://ATLAS_COOLPROD/(serverurl=http://xyzfrontier.cern.ch:8000/atlr)/schema
258 std::string::size_type ipos3=conn.find('(',ipos1+3);
259 if (ipos3!=std::string::npos && ipos3<ipos2) ipos2=ipos3;
260 if (ipos1!=std::string::npos && ipos2!=std::string::npos && !veto) {
261 const std::string server=conn.substr(ipos1+3,ipos2-ipos1-3);
262 // check if this server is on list of replicas to use for domain
263 // if so, add it with its associated priority
264 for (const auto& [name, pri] : m_servermap) {
265 if (name==server) {
266 primap[pri+spri]=dbdescr;
267 }
268 }
269 }
270 }
271 }
272 // now create sorted list
273 replicaSet.clear();
274 for (const auto& [pri, db] : primap) {
275 replicaSet.push_back(db);
276 ATH_MSG_DEBUG ("Allowed replica to try (priority " << pri << ") : " << db->connectionString());
277 }
278 if (replicaSet.empty()) {
279 ATH_MSG_ERROR ("No matching replicas found");
280 }
281 ATH_MSG_DEBUG ("Retained total of " << replicaSet.size() << " replicas");
282}
std::vector< std::string > veto
these patterns are anded
Definition listroot.cxx:191

Member Data Documentation

◆ m_configfile

Gaudi::Property<std::string> DBReplicaSvc::m_configfile {this, "ConfigFile", "dbreplica.config"}
private

Definition at line 29 of file DBReplicaSvc.h.

29{this, "ConfigFile", "dbreplica.config"};

◆ m_connClean

Gaudi::Property<bool> DBReplicaSvc::m_connClean {this, "ConnectionCleanUp", false}
private

ConnectionCleanUp - whether to use CORAL connection management thread: default = false.

Definition at line 44 of file DBReplicaSvc.h.

44{this, "ConnectionCleanUp", false};

◆ m_context

coral::Context* DBReplicaSvc::m_context {nullptr}
private

Definition at line 49 of file DBReplicaSvc.h.

49{nullptr};

◆ m_coolsqlitepattern

Gaudi::Property<std::string> DBReplicaSvc::m_coolsqlitepattern {this, "COOLSQLiteVetoPattern", ""}
private

Definition at line 31 of file DBReplicaSvc.h.

31{this, "COOLSQLiteVetoPattern", ""};

◆ m_frontierComp

Gaudi::Property<int> DBReplicaSvc::m_frontierComp {this, "FrontierCompression", 5}
private

Frontier proprties, compression level and list of schemas to be refreshed: default = 5.

Definition at line 46 of file DBReplicaSvc.h.

46{this, "FrontierCompression", 5};

◆ m_frontiergen

bool DBReplicaSvc::m_frontiergen {false}
private

Definition at line 50 of file DBReplicaSvc.h.

50{false};

◆ m_frontierRefresh

Gaudi::Property<std::vector<std::string> > DBReplicaSvc::m_frontierRefresh {this, "FrontierRefreshSchema", {}}
private

Definition at line 47 of file DBReplicaSvc.h.

47{this, "FrontierRefreshSchema", {}};

◆ m_hostname

std::string DBReplicaSvc::m_hostname
private

Definition at line 51 of file DBReplicaSvc.h.

◆ m_nofailover

Gaudi::Property<bool> DBReplicaSvc::m_nofailover {this, "DisableFailover", false}
private

Definition at line 35 of file DBReplicaSvc.h.

35{this, "DisableFailover", false};

◆ m_retrialPeriod

Gaudi::Property<int> DBReplicaSvc::m_retrialPeriod {this, "ConnectionRetrialPeriod", 300}
private

ConnectionRetrialPeriod, retry period for CORAL Connection Service: default = 30 seconds.

Definition at line 38 of file DBReplicaSvc.h.

38{this, "ConnectionRetrialPeriod", 300};

◆ m_retrialTimeOut

Gaudi::Property<int> DBReplicaSvc::m_retrialTimeOut {this, "ConnectionRetrialTimeOut", 3600}
private

ConnectionRetrialTimeOut, the retrial time out for CORAL Connection Service: default = 300 seconds.

Definition at line 40 of file DBReplicaSvc.h.

40{this, "ConnectionRetrialTimeOut", 3600};

◆ m_servermap

std::vector<ServerPair> DBReplicaSvc::m_servermap
private

Definition at line 53 of file DBReplicaSvc.h.

◆ m_testhost

Gaudi::Property<std::string> DBReplicaSvc::m_testhost {this, "TestHost", ""}
private

Definition at line 30 of file DBReplicaSvc.h.

30{this, "TestHost", ""};

◆ m_timeOut

Gaudi::Property<int> DBReplicaSvc::m_timeOut {this, "ConnectionTimeOut", 5}
private

ConnectionTimeOut, the time out for CORAL Connection Service: default = 5 seconds.

Definition at line 42 of file DBReplicaSvc.h.

42{this, "ConnectionTimeOut", 5};

◆ m_usecoolfrontier

Gaudi::Property<bool> DBReplicaSvc::m_usecoolfrontier {this, "UseCOOLFrontier", true}
private

Definition at line 33 of file DBReplicaSvc.h.

33{this, "UseCOOLFrontier", true};

◆ m_usecoolsqlite

Gaudi::Property<bool> DBReplicaSvc::m_usecoolsqlite {this, "UseCOOLSQLite", true}
private

Definition at line 32 of file DBReplicaSvc.h.

32{this, "UseCOOLSQLite", true};

◆ m_usegeomsqlite

Gaudi::Property<bool> DBReplicaSvc::m_usegeomsqlite {this, "UseGeomSQLite", true}
private

Definition at line 34 of file DBReplicaSvc.h.

34{this, "UseGeomSQLite", true};

The documentation for this class was generated from the following files: