NCBI C++ ToolKit
reader_service.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: reader_service.cpp 99612 2023-04-25 15:21:50Z vasilche $
2 * ===========================================================================
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 * ===========================================================================
23 *
24 * Author: Eugene Vasilchenko
25 *
26 * File Description: Common class to control ID1/ID2 service connections
27 *
28 */
29 
30 #include <ncbi_pch.hpp>
31 #include <corelib/ncbi_param.hpp>
32 #include <corelib/ncbi_config.hpp>
36 #include <corelib/ncbitime.hpp>
37 #include <corelib/ncbithr.hpp>
38 #include <connect/ncbi_socket.hpp>
39 #include <cmath>
40 
43 
44 class CReader;
45 
46 #define DEFAULT_TIMEOUT 20
47 #define DEFAULT_OPEN_TIMEOUT 5
48 #define DEFAULT_OPEN_TIMEOUT_MAX 30
49 #define DEFAULT_OPEN_TIMEOUT_MULTIPLIER 1.5
50 #define DEFAULT_OPEN_TIMEOUT_INCREMENT 0
51 
53  {
55  0,
57  },
58  {
62  },
63  {
67  },
68  {
72  }
73 };
74 
76 
77 
78 NCBI_PARAM_DECL(int, GENBANK, CONN_DEBUG);
79 NCBI_PARAM_DEF_EX(int, GENBANK, CONN_DEBUG, 0,
80  eParam_NoThread, GENBANK_CONN_DEBUG);
81 
82 static int s_GetDebugLevel(void)
83 {
84  static CSafeStatic<NCBI_PARAM_TYPE(GENBANK, CONN_DEBUG)> s_Value;
85  return s_Value->Get();
86 }
87 
88 
90 {
91  /// C Language deallocation function.
92  static void Delete(SConnNetInfo* object)
93  { ConnNetInfo_Destroy(object); }
94 };
95 
96 
97 struct SServerScanInfo : public CObject
98 {
99  typedef vector< AutoPtr<SSERV_Info, CDeleter<SSERV_Info> > > TSkipServers;
100  SServerScanInfo(const TSkipServers& skip_servers)
101  : m_TotalCount(0),
102  m_SkippedCount(0),
103  m_CurrentServer(0),
104  m_SkipServers(skip_servers)
105  {
106  }
111 
112  void Reset(void) {
113  m_TotalCount = 0;
114  m_SkippedCount = 0;
115  m_CurrentServer = 0;
116  }
117  bool SkipServer(const SSERV_Info* server);
118 };
119 
120 
122 {
123  ++m_TotalCount;
125  if ( SERV_EqualInfo(server, it->get()) ) {
126  ++m_SkippedCount;
127  return true;
128  }
129  }
130  return false;
131 }
132 
133 
135 {
136  /// C Language deallocation function.
137  static void Delete(SConnNetInfo* object) {
138  ConnNetInfo_Destroy(object);
139  }
140 };
141 
142 
143 static void s_ScanInfoReset(void* data)
144 {
145  SServerScanInfo* scan_info = static_cast<SServerScanInfo*>(data);
146  scan_info->Reset();
147 }
148 
149 
150 static void s_ScanInfoCleanup(void* data)
151 {
152  SServerScanInfo* scan_info = static_cast<SServerScanInfo*>(data);
153  scan_info->RemoveReference();
154 }
155 
156 
157 static const SSERV_Info* s_ScanInfoGetNextInfo(void* data, SERV_ITER iter)
158 {
159  SServerScanInfo* scan_info = static_cast<SServerScanInfo*>(data);
160  const SSERV_Info* info = SERV_GetNextInfo(iter);
161  while ( info && scan_info->SkipServer(info) ) {
162  info = SERV_GetNextInfo(iter);
163  }
164  scan_info->m_CurrentServer = info;
165  return info;
166 }
167 
168 
171 {
172  SConnInfo info;
173 
174  STimeout tmout;
175  SetOpenTimeoutTo(&tmout, error_count);
176 
177  CRef<SServerScanInfo> scan_info;
178 
179  if ( NStr::StartsWith(m_ServiceName, "http://") ||
180  NStr::StartsWith(m_ServiceName, "https://") ) {
181  if ( s_GetDebugLevel() > 0 ) {
182  CDebugPrinter s("CReaderConnector");
183  s << "Opening HTTP connection to " << m_ServiceName;
184  }
185  info.m_Stream.reset(new CConn_HttpStream(m_ServiceName));
186  if ( s_GetDebugLevel() > 0 ) {
187  CDebugPrinter s("CReaderConnector");
188  s << "Opened HTTP connection to "<<m_ServiceName;
189  }
190  }
191  else {
194  net_info->max_try = 1;
195 
196  if ( !m_SkipServers.empty() && s_GetDebugLevel() > 0 ) {
197  CDebugPrinter s("CReaderConnector");
198  s << "skip:";
200  s << " " << CSocketAPI::ntoa(it->get()->host);
201  }
202  }
204  SSERVICE_Extra params;
205  memset(&params, 0, sizeof(params));
206  params.reset = s_ScanInfoReset;
207  params.cleanup = s_ScanInfoCleanup;
209  params.flags = fHTTP_NoAutoRetry;
210 
211  if ( s_GetDebugLevel() > 0 ) {
212  CDebugPrinter s("CReaderConnector");
213  s << "Opening service connection to " << m_ServiceName;
214  }
215  params.data = scan_ptr;
216  scan_ptr->AddReference();
217  info.m_Stream.reset(new CConn_ServiceStream(m_ServiceName, fSERV_Any,
218  net_info.get(),
219  &params,
220  &tmout));
221  if ( s_GetDebugLevel() > 0 ) {
222  CDebugPrinter s("CReaderConnector");
223  s << "Opened service connection to " << m_ServiceName;
224  }
225  scan_info = scan_ptr;
226  }
227 
228  CConn_IOStream& stream = *info.m_Stream;
229  // need to call CONN_Wait to force connection to open
230  if ( !stream.bad() ) {
231  if ( s_GetDebugLevel() > 0 ) {
232  CDebugPrinter s("CReaderConnector");
233  s << "Waiting for connector...";
234  }
235  CONN_Wait(stream.GetCONN(), eIO_Write, &tmout);
236  if ( s_GetDebugLevel() > 0 ) {
237  CDebugPrinter s("CReaderConnector");
238  s << "Got connector.";
239  }
240  if ( scan_info ) {
241  info.m_ServerInfo = scan_info->m_CurrentServer;
242  }
243  }
244  if ( scan_info && s_GetDebugLevel() > 0 ) {
245  CDebugPrinter s("CReaderConnector");
246  s << "servers:";
247  s << " total: "<<scan_info->m_TotalCount;
248  s << " skipped: "<<scan_info->m_SkippedCount;
249  }
250  if ( scan_info && !m_SkipServers.empty() &&
251  scan_info->m_TotalCount == scan_info->m_SkippedCount ) {
252  if ( s_GetDebugLevel() > 0 ) {
253  CDebugPrinter s("CReaderConnector");
254  s << "Clearing skip servers.";
255  }
256  // all servers are skipped, reset skip-list
257  m_SkipServers.clear();
258  }
259  return info;
260 }
261 
262 
264 {
265  string ret = m_ServiceName;
266  CONN conn = stream.GetCONN();
267  if ( conn ) {
269  if ( descr ) {
270  ret += " -> ";
271  ret += descr.get();
272  }
273  }
274  return ret;
275 }
276 
277 
279  : m_Timeout(DEFAULT_TIMEOUT),
280  m_OpenTimeout(s_OpenTimeoutParams)
281 {
282 }
283 
284 
286  : m_ServiceName(service_name),
287  m_Timeout(DEFAULT_TIMEOUT),
288  m_OpenTimeout(s_OpenTimeoutParams)
289 {
290 }
291 
292 
294 {
295 }
296 
297 
298 void CReaderServiceConnector::SetServiceName(const string& service_name)
299 {
300  m_ServiceName = service_name;
301  m_SkipServers.clear();
302 }
303 
304 
306  const string& driver_name)
307 {
308  m_Timeout = conf.GetInt(driver_name,
312  m_OpenTimeout.Init(conf, driver_name, s_OpenTimeoutParams);
313 }
314 
315 
317 {
318  if ( conn_info.m_ServerInfo ) {
319  // server failed without any reply, remember to skip it next time
320  m_SkipServers.push_back(SERV_CopyInfo(conn_info.m_ServerInfo));
321  if ( s_GetDebugLevel() > 0 ) {
322  CDebugPrinter s("CReaderConnector");
323  s << "added skip: "<<
324  CSocketAPI::ntoa(m_SkipServers.back().get()->host);
325  }
326  conn_info.m_ServerInfo = 0;
327  }
328 }
329 
330 
332  double timeout)
333 {
334  tmout->sec = unsigned(timeout);
335  tmout->usec = unsigned((timeout-tmout->sec)*1e6);
336 }
337 
338 
AutoPtr –.
Definition: ncbimisc.hpp:401
This stream exchanges data with an HTTP server located at the URL: http[s]://host[:port]/path[?...
Base class, inherited from "std::iostream", does both input and output, using the specified CONNECTOR...
This stream exchanges data with a named service, in a constraint that the service is implemented as o...
void Init(CConfig &conf, const string &driver_name, const SAllParams &params)
Definition: incr_time.cpp:61
CObject –.
Definition: ncbiobj.hpp:180
void SetOpenTimeoutTo(STimeout *tmout, int error_count) const
void RememberIfBad(SConnInfo &conn_info)
void InitTimeouts(CConfig &conf, const string &driver_name)
SConnInfo Connect(int error_count=0)
string GetConnDescription(CConn_IOStream &stream) const
CIncreasingTime m_OpenTimeout
void SetServiceName(const string &service_name)
static void x_SetTimeoutTo(STimeout *tmout, double timeout)
vector< AutoPtr< SSERV_Info, CDeleter< SSERV_Info > > > TSkipServers
CRef –.
Definition: ncbiobj.hpp:618
CSafeStatic<>::
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
char data[12]
Definition: iconv.c:80
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:469
CONN GetCONN(void) const
char * CONN_Description(CONN conn)
Return a human-readable description of the connection as a character '\0'-terminated string.
FSERVICE_GetNextInfo get_next_info
EIO_Status CONN_Wait(CONN conn, EIO_Event event, const STimeout *timeout)
Block on the connection until it becomes available for either reading or writing (depending on "event...
FSERVICE_Cleanup cleanup
FSERVICE_Reset reset
@ fHTTP_NoAutoRetry
No auto-retries allowed.
int GetInt(const string &driver_name, const string &param_name, EErrAction on_error, int default_value, const list< string > *synonyms=NULL)
Utility function to get an integer element of parameter tree Throws an exception when mandatory param...
@ eErr_NoThrow
Return default value on error.
void RemoveReference(void) const
Remove reference to object.
Definition: ncbiobj.hpp:500
#define NCBI_PARAM_TYPE(section, name)
Generate typename for a parameter from its {section, name} attributes.
Definition: ncbi_param.hpp:149
@ eParam_NoThread
Do not use per-thread values.
Definition: ncbi_param.hpp:418
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
SSERV_Info * SERV_CopyInfo(const SSERV_Info *info)
SSERV_InfoCPtr SERV_GetNextInfo(SERV_ITER iter)
Same as "SERV_GetNextInfoEx(., 0)" – i.e.
Definition: ncbi_service.c:936
int SERV_EqualInfo(const SSERV_Info *info1, const SSERV_Info *info2)
@ fSERV_Any
Definition: ncbi_service.h:79
static string ntoa(unsigned int host)
BSD-like API. NB: when int, "host" must be in network byte order.
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5406
unsigned int usec
microseconds (modulo 1,000,000)
Definition: ncbi_types.h:78
unsigned int sec
seconds
Definition: ncbi_types.h:77
SConnNetInfo * ConnNetInfo_Create(const char *service)
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
@ eIO_Write
write
Definition: ncbi_core.h:121
static MDB_envinfo info
Definition: mdb_load.c:37
string s_Value(TValue value)
Parameters initialization model.
Multi-threading – classes, functions, and features.
Defines: CTimeFormat - storage class for time format.
static int error_count
Definition: pcre2grep.c:246
static void s_ScanInfoCleanup(void *data)
#define DEFAULT_OPEN_TIMEOUT_MULTIPLIER
NCBI_PARAM_DECL(int, GENBANK, CONN_DEBUG)
static void s_ScanInfoReset(void *data)
NCBI_PARAM_DEF_EX(int, GENBANK, CONN_DEBUG, 0, eParam_NoThread, GENBANK_CONN_DEBUG)
#define DEFAULT_OPEN_TIMEOUT_MAX
static const SSERV_Info * s_ScanInfoGetNextInfo(void *data, SERV_ITER iter)
#define DEFAULT_OPEN_TIMEOUT_INCREMENT
static int s_GetDebugLevel(void)
#define DEFAULT_OPEN_TIMEOUT
#define DEFAULT_TIMEOUT
CReader::CDebugPrinter CDebugPrinter
static CIncreasingTime::SAllParams s_OpenTimeoutParams
#define NCBI_GBLOADER_READER_PARAM_OPEN_TIMEOUT_MAX
#define NCBI_GBLOADER_READER_PARAM2_OPEN_TIMEOUT_MAX
#define NCBI_GBLOADER_READER_PARAM_OPEN_TIMEOUT_INCREMENT
#define NCBI_GBLOADER_READER_PARAM_TIMEOUT
#define NCBI_GBLOADER_READER_PARAM2_OPEN_TIMEOUT_MULTIPLIER
#define NCBI_GBLOADER_READER_PARAM2_OPEN_TIMEOUT_INCREMENT
#define NCBI_GBLOADER_READER_PARAM_OPEN_TIMEOUT
#define NCBI_GBLOADER_READER_PARAM_OPEN_TIMEOUT_MULTIPLIER
static void Delete(SConnNetInfo *object)
C Language deallocation function.
static void Delete(SConnNetInfo *object)
C Language deallocation function.
bool SkipServer(const SSERV_Info *server)
SServerScanInfo(const TSkipServers &skip_servers)
const SSERV_Info * m_CurrentServer
const TSkipServers & m_SkipServers
vector< AutoPtr< SSERV_Info, CDeleter< SSERV_Info > > > TSkipServers
Timeout structure.
Definition: ncbi_types.h:76
Modified on Fri Sep 20 14:58:07 2024 by modify_doxy.py rev. 669887