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

Go to the SVN repository for this file.

1 /* $Id: reader_id2.cpp 98784 2023-01-05 19:40:28Z 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  *
25  * Author: Eugene Vasilchenko
26  *
27  * File Description: Data reader from ID2
28  *
29  */
30 
31 #include <ncbi_pch.hpp>
32 #include <corelib/ncbi_param.hpp>
33 #include <corelib/ncbi_config.hpp>
34 
38 #include <objtools/data_loaders/genbank/readers.hpp> // for entry point
41 #include <objtools/error_codes.hpp>
42 
44 #include <objmgr/impl/tse_info.hpp>
47 
49 
50 #include <corelib/ncbimtx.hpp>
51 
53 
58 #include <objects/id2/id2__.hpp>
62 
63 #include <serial/iterator.hpp>
64 #include <serial/objistrasnb.hpp>
65 
67 
69 
70 #include <iomanip>
71 
72 
73 #define NCBI_USE_ERRCODE_X Objtools_Reader_Id2
74 
77 
78 #define DEFAULT_SERVICE "ID2"
79 #define DEFAULT_NUM_CONN 3
80 #define MAX_MT_CONN 256
81 
82 //#define GENBANK_ID2_RANDOM_FAILS 1
83 #define GENBANK_ID2_RANDOM_FAILS_FREQUENCY 20
84 #define GENBANK_ID2_RANDOM_FAILS_RECOVER 10 // new + write + read
85 
86 #ifdef GENBANK_ID2_RANDOM_FAILS
87 static int& GetFailCounter(CId2Reader::TConn /*conn*/)
88 {
89 #ifdef NCBI_THREADS
90  static CStaticTls<int> fail_counter;
91  int* ptr = fail_counter.GetValue();
92  if ( !ptr ) {
93  ptr = new int(0);
94  fail_counter.SetValue(ptr);
95  }
96  return *ptr;
97 #else
98  static int fail_counter = 0;
99  return fail_counter;
100 #endif
101 }
102 
104 {
105  int& value = GetFailCounter(conn);
107  return;
108  }
109  if ( rand() % GENBANK_ID2_RANDOM_FAILS_FREQUENCY == 0 ) {
110  value = 0;
111  stream.setstate(ios::badbit);
112  }
113 }
114 #else
115 # define SetRandomFail(stream, conn) do{}while(0)
116 #endif
117 
118 
119 NCBI_PARAM_DECL(string, GENBANK, ID2_CGI_NAME);
120 NCBI_PARAM_DECL(string, GENBANK, ID2_SERVICE_NAME);
121 NCBI_PARAM_DECL(string, NCBI, SERVICE_NAME_ID2);
122 
123 NCBI_PARAM_DEF_EX(string, GENBANK, ID2_CGI_NAME, "",
124  eParam_NoThread, GENBANK_ID2_CGI_NAME);
125 NCBI_PARAM_DEF_EX(string, GENBANK, ID2_SERVICE_NAME, "",
126  eParam_NoThread, GENBANK_ID2_SERVICE_NAME);
127 NCBI_PARAM_DEF_EX(string, NCBI, SERVICE_NAME_ID2, DEFAULT_SERVICE,
128  eParam_NoThread, GENBANK_SERVICE_NAME_ID2);
129 
130 CId2Reader::CId2Reader(int max_connections)
131  : m_Connector(DEFAULT_SERVICE)
132 {
133  SetMaximumConnections(max_connections, DEFAULT_NUM_CONN);
134 }
135 
136 
138  const string& driver_name)
139 {
140  CConfig conf(params);
141  string service_name = conf.GetString(
142  driver_name,
145  kEmptyStr);
146  if ( service_name.empty() ) {
147  service_name = NCBI_PARAM_TYPE(GENBANK, ID2_CGI_NAME)::GetDefault();
148  }
149  if ( service_name.empty() ) {
150  service_name = NCBI_PARAM_TYPE(GENBANK,ID2_SERVICE_NAME)::GetDefault();
151  }
152  if ( service_name.empty() ) {
153  service_name = NCBI_PARAM_TYPE(NCBI, SERVICE_NAME_ID2)::GetDefault();
154  }
155  m_Connector.SetServiceName(service_name);
156  m_Connector.InitTimeouts(conf, driver_name);
157  CReader::InitParams(conf, driver_name, DEFAULT_NUM_CONN);
158 }
159 
160 
162 {
163 }
164 
165 
167 {
168 #ifdef NCBI_THREADS
169  return MAX_MT_CONN;
170 #else
171  return 1;
172 #endif
173 }
174 
175 
177 {
178  _ASSERT(!m_Connections.count(conn));
180 }
181 
182 
184 {
186 }
187 
188 
190 {
191  _ASSERT(m_Connections.count(conn));
193  m_Connector.RememberIfBad(conn_info);
194  if ( conn_info.m_Stream ) {
195  x_ReportDisconnect("CId2Reader", "ID2", conn, failed);
196  if ( GetDebugLevel() >= eTraceOpen ) {
197  CDebugPrinter s(conn, "CId2Reader");
198  s << "Closing ID2 connection";
199  }
200  conn_info.m_Stream.reset();
201  if ( GetDebugLevel() >= eTraceOpen ) {
202  CDebugPrinter s(conn, "CId2Reader");
203  s << "Closed ID2 connection";
204  }
205  }
206 }
207 
208 
210 {
211  _ASSERT(m_Connections.count(conn));
213  if ( conn_info.m_Stream.get() ) {
214  return conn_info.m_Stream.get();
215  }
217  return m_Connections[conn].m_Stream.get();
218 }
219 
220 
222 {
224  return iter == m_Connections.end()? 0: iter->second.m_Stream.get();
225 }
226 
227 
229 {
230  return m_Connector.GetConnDescription(stream);
231 }
232 
233 
235 {
237  return stream? x_ConnDescription(*stream): "NULL";
238 }
239 
240 
242 {
243  if ( GetDebugLevel() >= eTraceOpen ) {
244  CDebugPrinter s(conn, "CId2Reader");
245  s << "New connection to " << m_Connector.GetServiceName() << "...";
246  }
247 
249 
250  CConn_IOStream& stream = *conn_info.m_Stream;
251  SetRandomFail(stream, conn);
252  if ( stream.bad() ) {
253  NCBI_THROW(CLoaderException, eConnectionFailed,
254  "cannot open connection: "+x_ConnDescription(stream));
255  }
256 
257  if ( GetDebugLevel() >= eTraceOpen ) {
258  CDebugPrinter s(conn, "CId2Reader");
259  s << "New connection: " << x_ConnDescription(stream);
260  }
261  try {
262  x_InitConnection(stream, conn);
263  }
264  catch ( CException& exc ) {
265  m_Connector.RememberIfBad(conn_info);
266  NCBI_RETHROW(exc, CLoaderException, eConnectionFailed,
267  "connection initialization failed: "+
268  x_ConnDescription(stream));
269  }
270  SetRandomFail(stream, conn);
271  if ( stream.bad() ) {
272  NCBI_THROW(CLoaderException, eConnectionFailed,
273  "connection initialization failed: "+
274  x_ConnDescription(stream));
275  }
276  // successfully received reply, server is good, forget it
277  conn_info.MarkAsGood();
278 
279  STimeout tmout;
280  m_Connector.SetTimeoutTo(&tmout);
281  CONN_SetTimeout(stream.GetCONN(), eIO_ReadWrite, &tmout);
282  tmout.sec = 0; tmout.usec = 1; // no wait on close
283  CONN_SetTimeout(stream.GetCONN(), eIO_Close, &tmout);
284 
285  m_Connections[conn] = conn_info;
286 }
287 
288 
289 #define MConnFormat MSerial_AsnBinary
290 
291 
293 {
294  // prepare init request
295  CID2_Request req;
296  req.SetRequest().SetInit();
297  x_SetContextData(req);
298  CID2_Request_Packet packet;
299  packet.Set().push_back(Ref(&req));
300  // that's it for now
301  // TODO: add params
302 
303  // send init request
304  {{
305  if ( GetDebugLevel() >= eTraceConn ) {
306  CDebugPrinter s(conn, "CId2Reader");
307  s << "Sending";
308  if ( GetDebugLevel() >= eTraceASN ) {
309  s << ": " << MSerial_AsnText << packet;
310  }
311  else {
312  s << " ID2-Request-Packet";
313  }
314  s << "...";
315  }
316  try {
317  stream << MConnFormat << packet << flush;
318  }
319  catch ( CException& exc ) {
320  NCBI_RETHROW(exc, CLoaderException, eConnectionFailed,
321  "failed to send init request: "+
322  x_ConnDescription(stream));
323  }
324  if ( GetDebugLevel() >= eTraceConn ) {
325  CDebugPrinter s(conn, "CId2Reader");
326  s << "Sent ID2-Request-Packet.";
327  }
328  if ( !stream ) {
329  NCBI_THROW(CLoaderException, eConnectionFailed,
330  "failed to send init request: "+
331  x_ConnDescription(stream));
332  }
333  }}
334 
335  // receive init reply
336  CID2_Reply reply;
337  {{
338  if ( GetDebugLevel() >= eTraceConn ) {
339  CDebugPrinter s(conn, "CId2Reader");
340  s << "Receiving ID2-Reply...";
341  }
342  stream >> MConnFormat >> reply;
343  if ( GetDebugLevel() >= eTraceConn ) {
344  CDebugPrinter s(conn, "CId2Reader");
345  s << "Received";
346  if ( GetDebugLevel() >= eTraceASN ) {
347  s << ": " << MSerial_AsnText << reply;
348  }
349  else {
350  s << " ID2-Reply.";
351  }
352  }
353  if ( !stream ) {
354  NCBI_THROW(CLoaderException, eLoaderFailed,
355  "failed to receive init reply: "+
356  x_ConnDescription(stream));
357  }
358  }}
359 
360  // check init reply
361  if ( reply.IsSetDiscard() ) {
362  NCBI_THROW(CLoaderException, eLoaderFailed,
363  "bad init reply: 'discard' is set: "+
364  x_ConnDescription(stream));
365  }
366  if ( reply.IsSetError() ) {
367  NCBI_THROW(CLoaderException, eLoaderFailed,
368  "bad init reply: 'error' is set: "+
369  x_ConnDescription(stream));
370  }
371  if ( !reply.IsSetEnd_of_reply() ) {
372  NCBI_THROW(CLoaderException, eLoaderFailed,
373  "bad init reply: 'end-of-reply' is not set: "+
374  x_ConnDescription(stream));
375  }
376  if ( reply.GetReply().Which() != CID2_Reply::TReply::e_Init ) {
377  NCBI_THROW(CLoaderException, eLoaderFailed,
378  "bad init reply: 'reply' is not 'init': "+
379  x_ConnDescription(stream));
380  }
381  // that's it for now
382  // TODO: process params
383 }
384 
385 
387 {
388  CConn_IOStream& stream = *x_GetConnection(conn);
389  stream << MConnFormat << packet << flush;
390 }
391 
392 
394 {
395  CConn_IOStream& stream = *x_GetConnection(conn);
396  SetRandomFail(stream, conn);
397  CObjectIStreamAsnBinary in(stream);
399  if ( !stream ) {
400  NCBI_THROW(CLoaderException, eConnectionFailed,
401  "failed to receive reply: "+
402  x_ConnDescription(stream));
403  }
404  // successfully receved reply, server is good, forget it
405  m_Connections[conn].MarkAsGood();
406 }
407 
408 
409 /////////////////////////////////////////////////////////////////////////////
410 /////////////////////////////////////////////////////////////////////////////
411 /////////////////////////////////////////////////////////////////////////////
412 
413 
415 
417 {
418  RegisterEntryPoint<objects::CReader>(NCBI_EntryPoint_Id2Reader);
419 }
420 
421 
422 /// Class factory for ID2 reader
423 ///
424 /// @internal
425 ///
426 class CId2ReaderCF :
427  public CSimpleClassFactoryImpl<objects::CReader, objects::CId2Reader>
428 {
429 public:
430  typedef CSimpleClassFactoryImpl<objects::CReader,
431  objects::CId2Reader> TParent;
432 public:
436 
437  objects::CReader*
438  CreateInstance(const string& driver = kEmptyStr,
440  NCBI_INTERFACE_VERSION(objects::CReader),
441  const TPluginManagerParamTree* params = 0) const
442  {
443  objects::CReader* drv = 0;
444  if ( !driver.empty() && driver != m_DriverName ) {
445  return 0;
446  }
447  if (version.Match(NCBI_INTERFACE_VERSION(objects::CReader))
449  drv = new objects::CId2Reader(params, driver);
450  }
451  return drv;
452  }
453 };
454 
455 
459 {
461 }
462 
463 
467 {
468  NCBI_EntryPoint_Id2Reader(info_list, method);
469 }
470 
471 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
Base class, inherited from "std::iostream", does both input and output, using the specified CONNECTOR...
CID2_Reply –.
Definition: ID2_Reply.hpp:66
CID2_Request_Packet –.
CID2_Request –.
Definition: ID2_Request.hpp:66
virtual void x_ReceiveReply(TConn conn, CID2_Reply &reply)=0
void x_SetContextData(CID2_Request &request)
static int GetDebugLevel(void)
Class factory for ID2 reader.
Definition: reader_id2.cpp:428
objects::CReader * CreateInstance(const string &driver=kEmptyStr, CVersionInfo version=NCBI_INTERFACE_VERSION(objects::CReader), const TPluginManagerParamTree *params=0) const
Create instance of TDriver.
Definition: reader_id2.cpp:438
CSimpleClassFactoryImpl< objects::CReader, objects::CId2Reader > TParent
Definition: reader_id2.cpp:431
virtual void x_DisconnectAtSlot(TConn conn, bool failed)
Definition: reader_id2.cpp:189
CConn_IOStream * x_GetCurrentConnection(TConn conn) const
Definition: reader_id2.cpp:221
virtual void x_AddConnectionSlot(TConn conn)
Definition: reader_id2.cpp:176
virtual void x_RemoveConnectionSlot(TConn conn)
Definition: reader_id2.cpp:183
virtual void x_SendPacket(TConn conn, const CID2_Request_Packet &packet)
Definition: reader_id2.cpp:386
void x_InitConnection(CConn_IOStream &stream, TConn conn)
Definition: reader_id2.cpp:292
CReaderServiceConnector m_Connector
Definition: reader_id2.hpp:69
CId2Reader(int max_connections=0)
Definition: reader_id2.cpp:130
int GetMaximumConnectionsLimit(void) const
Definition: reader_id2.cpp:166
TConnections m_Connections
Definition: reader_id2.hpp:72
virtual void x_ReceiveReply(TConn conn, CID2_Reply &reply)
Definition: reader_id2.cpp:393
virtual void x_ConnectAtSlot(TConn conn)
Definition: reader_id2.cpp:241
virtual string x_ConnDescription(TConn conn) const
Definition: reader_id2.cpp:234
CConn_IOStream * x_GetConnection(TConn conn)
Definition: reader_id2.cpp:209
Data loader exceptions, used by GenBank loader.
CObjectIStreamAsnBinary –.
Definition: objistrasnb.hpp:59
void RememberIfBad(SConnInfo &conn_info)
void SetTimeoutTo(STimeout *tmout) const
void InitTimeouts(CConfig &conf, const string &driver_name)
SConnInfo Connect(int error_count=0)
string GetConnDescription(CConn_IOStream &stream) const
const string & GetServiceName(void) const
void SetServiceName(const string &service_name)
unsigned TConn
Definition: reader.hpp:87
void x_ReportDisconnect(const char *reader, const char *server, TConn conn, bool failed) const
Definition: reader.cpp:444
virtual void OpenConnection(TConn conn)
Definition: reader.cpp:326
void InitParams(CConfig &conf, const string &driver_name, int default_max_conn)
Definition: reader.cpp:131
int SetMaximumConnections(int max)
Definition: reader.cpp:228
Template class helps to implement one driver class factory.
definition of a Culling tree
Definition: ncbi_tree.hpp:100
CVersionInfo –.
void erase(iterator pos)
Definition: map.hpp:167
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
int failed
Definition: dbmorecmds.c:10
void reset(element_type *p=0, EOwnership ownership=eTakeOwnership)
Reset will delete the old pointer (if owned), set content to the new value, and assume the ownership ...
Definition: ncbimisc.hpp:480
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:469
CONN GetCONN(void) const
EIO_Status CONN_SetTimeout(CONN conn, EIO_Event event, const STimeout *timeout)
Specify timeout for the connection I/O, including "Connect" (aka "Open") and "Close".
#define _VERIFY(expr)
Definition: ncbidbg.hpp:161
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
#define NCBI_RETHROW(prev_exception, exception_class, err_code, message)
Generic macro to re-throw an exception.
Definition: ncbiexpt.hpp:737
#define MSerial_AsnText
I/O stream manipulators –.
Definition: serialbase.hpp:696
string GetString(const string &driver_name, const string &param_name, EErrAction on_error, const string &default_value, const list< string > *synonyms=NULL)
Utility function to get an element of parameter tree Throws an exception when mandatory parameter is ...
@ eErr_NoThrow
Return default value on error.
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
#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
static void NCBI_EntryPointImpl(TDriverInfoList &info_list, EEntryPointRequest method)
Entry point implementation.
#define NCBI_INTERFACE_VERSION(iface)
Macro to construct CVersionInfo class using interface name (relies on CInterfaceVersion class)
list< SDriverInfo > TDriverInfoList
List of driver information.
EEntryPointRequest
Actions performed by the entry point.
#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
IO_PREFIX::iostream CNcbiIostream
Portable alias for iostream.
Definition: ncbistre.hpp:152
#define kEmptyStr
Definition: ncbistr.hpp:123
TValue * GetValue(void)
Definition: ncbithr.hpp:335
void SetValue(TValue *value, FCleanup cleanup=0, void *cleanup_data=0, CTlsBase::ENativeThreadCleanup native=CTlsBase::eSkipCleanup)
Definition: ncbithr.hpp:338
unsigned int usec
microseconds (modulo 1,000,000)
Definition: ncbi_types.h:78
unsigned int sec
seconds
Definition: ncbi_types.h:77
@ eIO_ReadWrite
eIO_Read | eIO_Write (also, eCONN_OnFlush)
Definition: ncbi_core.h:122
@ eIO_Close
also serves as an error indicator in SOCK_Poll
Definition: ncbi_core.h:123
@ eNonCompatible
major, minor does not match
E_Choice Which(void) const
Which variant is currently selected.
Definition: ID2_Reply_.hpp:710
bool IsSetDiscard(void) const
Check if a value has been assigned to Discard data member.
Definition: ID2_Reply_.hpp:958
const TReply & GetReply(void) const
Get the Reply member data.
Definition: ID2_Reply_.hpp:940
Tdata & Set(void)
Assign a value to data member.
bool IsSetError(void) const
Check if a value has been assigned to Error data member.
Definition: ID2_Reply_.hpp:879
void SetRequest(TRequest &value)
Assign a value to Request data member.
bool IsSetEnd_of_reply(void) const
true if this reply is the last one for the request false if more replies will follow Check if a value...
Definition: ID2_Reply_.hpp:904
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
Definition of all error codes used in objtools libraries.
const string version
version string
Definition: variables.hpp:66
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
Parameters initialization model.
Multi-threading – mutexes; rw-locks; semaphore.
std::istream & in(std::istream &in_, double &x_)
Helper classes and templates to implement plugins.
#define MAX_MT_CONN
Definition: reader_id2.cpp:80
#define DEFAULT_NUM_CONN
Definition: reader_id2.cpp:79
#define GENBANK_ID2_RANDOM_FAILS_RECOVER
Definition: reader_id2.cpp:84
NCBI_PARAM_DECL(string, GENBANK, ID2_CGI_NAME)
#define GENBANK_ID2_RANDOM_FAILS_FREQUENCY
Definition: reader_id2.cpp:83
#define MConnFormat
Definition: reader_id2.cpp:289
#define DEFAULT_SERVICE
Definition: reader_id2.cpp:78
NCBI_PARAM_DEF_EX(string, GENBANK, ID2_CGI_NAME, "", eParam_NoThread, GENBANK_ID2_CGI_NAME)
#define SetRandomFail(stream, conn)
Definition: reader_id2.cpp:115
void NCBI_EntryPoint_Id2Reader(CPluginManager< objects::CReader >::TDriverInfoList &info_list, CPluginManager< objects::CReader >::EEntryPointRequest method)
Definition: reader_id2.cpp:456
void GenBankReaders_Register_Id2(void)
Definition: reader_id2.cpp:416
void NCBI_EntryPoint_xreader_id2(CPluginManager< objects::CReader >::TDriverInfoList &info_list, CPluginManager< objects::CReader >::EEntryPointRequest method)
Definition: reader_id2.cpp:464
#define NCBI_GBLOADER_READER_ID2_PARAM_SERVICE_NAME
#define NCBI_GBLOADER_READER_ID2_DRIVER_NAME
NCBI
Definition: static_set.hpp:72
AutoPtr< CConn_IOStream > m_Stream
Timeout structure.
Definition: ncbi_types.h:76
#define _ASSERT
Modified on Fri Sep 20 14:58:05 2024 by modify_doxy.py rev. 669887