rpcbase.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:8k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: rpcbase.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/04/12 17:15:36  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [CATCHUP_003] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef SERIAL___RPCBASE__HPP
  10. #define SERIAL___RPCBASE__HPP
  11. /*  $Id: rpcbase.hpp,v 1000.1 2004/04/12 17:15:36 gouriano Exp $
  12. * ===========================================================================
  13. *
  14. *                            PUBLIC DOMAIN NOTICE
  15. *               National Center for Biotechnology Information
  16. *
  17. *  This software/database is a "United States Government Work" under the
  18. *  terms of the United States Copyright Act.  It was written as part of
  19. *  the author's official duties as a United States Government employee and
  20. *  thus cannot be copyrighted.  This software/database is freely available
  21. *  to the public for use. The National Library of Medicine and the U.S.
  22. *  Government have not placed any restriction on its use or reproduction.
  23. *
  24. *  Although all reasonable efforts have been taken to ensure the accuracy
  25. *  and reliability of the software and data, the NLM and the U.S.
  26. *  Government do not and cannot warrant the performance or results that
  27. *  may be obtained by using this software or data. The NLM and the U.S.
  28. *  Government disclaim all warranties, express or implied, including
  29. *  warranties of performance, merchantability or fitness for any particular
  30. *  purpose.
  31. *
  32. *  Please cite the author in any work or product based on this material.
  33. *
  34. * ===========================================================================
  35. *
  36. * Author:  Aaron Ucko, NCBI
  37. *
  38. * File Description:
  39. *   Generic template class for ASN.1/XML RPC clients
  40. *
  41. */
  42. #include <connect/ncbi_conn_stream.hpp>
  43. #include <corelib/ncbimtx.hpp>
  44. #include <serial/objistr.hpp>
  45. #include <serial/objostr.hpp>
  46. #include <serial/serial.hpp>
  47. /** @addtogroup UserCodeSupport
  48.  *
  49.  * @{
  50.  */
  51. BEGIN_NCBI_SCOPE
  52. /// CRPCClient -- prototype client for ASN.1/XML-based RPC.
  53. /// Normally connects automatically on the first real request and
  54. /// disconnects automatically in the destructor, but allows both events
  55. /// to occur explicitly.
  56. template <class TRequest, class TReply>
  57. class CRPCClient : public CObject
  58. {
  59. public:
  60.     CRPCClient(const string&     service     = kEmptyStr,
  61.                ESerialDataFormat format      = eSerial_AsnBinary,
  62.                unsigned int      retry_limit = 3)
  63.         : m_Service(service), m_Format(format), m_RetryLimit(retry_limit)
  64.         { }
  65.     virtual ~CRPCClient(void) { Disconnect(); }
  66.     virtual void Ask(const TRequest& request, TReply& reply);
  67.             void Connect(void);
  68.             void Disconnect(void);
  69.             void Reset(void);
  70.       EIO_Status SetTimeout(const STimeout* timeout,
  71.                             EIO_Event direction = eIO_ReadWrite);
  72. protected:
  73.     /// These run with m_Mutex already acquired.
  74.     virtual void x_Connect(void);
  75.     virtual void x_Disconnect(void);
  76.             void x_SetStream(CNcbiIostream* stream);
  77.     /// Retry policy; by default, just _TRACEs the event and returns
  78.     /// true.  May reset the connection (or do anything else, really),
  79.     /// but note that Ask will already automatically reconnect if the
  80.     /// stream is explicitly bad.  (Ask also takes care of enforcing
  81.     /// m_RetryLimit.)
  82.     virtual bool x_ShouldRetry(unsigned int tries);
  83. private:
  84.     typedef CRPCClient<TRequest, TReply> TSelf;
  85.     /// Prohibit default copy constructor and assignment operator.
  86.     CRPCClient(const TSelf& x);
  87.     bool operator= (const TSelf& x);
  88.     auto_ptr<CNcbiIostream>  m_Stream;
  89.     auto_ptr<CObjectIStream> m_In;
  90.     auto_ptr<CObjectOStream> m_Out;
  91.     string                   m_Service; ///< Used by default Connect().
  92.     ESerialDataFormat        m_Format;
  93.     CMutex                   m_Mutex;   ///< To allow sharing across threads.
  94. protected:
  95.     unsigned int             m_RetryLimit;
  96. };
  97. ///////////////////////////////////////////////////////////////////////////
  98. // Inline methods
  99. template <class TRequest, class TReply>
  100. inline
  101. void CRPCClient<TRequest, TReply>::Connect(void)
  102. {
  103.     if (m_Stream.get()  &&  m_Stream->good()) {
  104.         return; // already connected
  105.     }
  106.     CMutexGuard LOCK(m_Mutex);
  107.     // repeat test with mutex held to avoid races
  108.     if (m_Stream.get()  &&  m_Stream->good()) {
  109.         return; // already connected
  110.     }
  111.     x_Connect();
  112. }
  113. template <class TRequest, class TReply>
  114. inline
  115. void CRPCClient<TRequest, TReply>::Disconnect(void)
  116. {
  117.     CMutexGuard LOCK(m_Mutex);
  118.     if ( !m_Stream.get()  ||  !m_Stream->good() ) {
  119.         // not connected -- don't call x_Disconnect, which might
  120.         // temporarily reconnect to send a fini!
  121.         return;
  122.     }
  123.     x_Disconnect();
  124. }
  125. template <class TRequest, class TReply>
  126. inline
  127. void CRPCClient<TRequest, TReply>::Reset(void)
  128. {
  129.     CMutexGuard LOCK(m_Mutex);
  130.     if (m_Stream.get()  &&  m_Stream->good()) {
  131.         x_Disconnect();
  132.     }
  133.     x_Connect();
  134. }
  135. template <class TRequest, class TReply>
  136. inline
  137. EIO_Status CRPCClient<TRequest, TReply>::SetTimeout(const STimeout* timeout,
  138.                                                     EIO_Event direction)
  139. {
  140.     CConn_IOStream* conn_stream = dynamic_cast<CConn_IOStream*>(m_Stream.get());
  141.     if (conn_stream) {
  142.         return CONN_SetTimeout(conn_stream->GetCONN(), direction, timeout);
  143.     } else {
  144.         return eIO_NotSupported;
  145.     }
  146. }
  147. template <class TRequest, class TReply>
  148. inline
  149. void CRPCClient<TRequest, TReply>::Ask(const TRequest& request, TReply& reply)
  150. {
  151.     CMutexGuard LOCK(m_Mutex);
  152.     
  153.     for (unsigned int tries = 1;  tries <= m_RetryLimit;  ++tries) {
  154.         try {
  155.             Connect(); // No-op if already connected
  156.             *m_Out << request;
  157.             *m_In >> reply;
  158.             break;
  159.         } catch (CSerialException&) {
  160.             if ( !x_ShouldRetry(tries) ) {
  161.                 throw;
  162.             }
  163.         }
  164.     }
  165. }
  166. template <class TRequest, class TReply>
  167. inline
  168. void CRPCClient<TRequest, TReply>::x_Connect(void)
  169. {
  170.     _ASSERT( !m_Service.empty() );
  171.     x_SetStream(new CConn_ServiceStream(m_Service));
  172. }
  173. template <class TRequest, class TReply>
  174. inline
  175. void CRPCClient<TRequest, TReply>::x_Disconnect(void)
  176. {
  177.     m_In.reset();
  178.     m_Out.reset();
  179.     m_Stream.reset();
  180. }
  181. template <class TRequest, class TReply>
  182. inline
  183. void CRPCClient<TRequest, TReply>::x_SetStream(CNcbiIostream* stream)
  184. {
  185.     m_Stream.reset(stream);
  186.     m_In .reset(CObjectIStream::Open(m_Format, *stream));
  187.     m_Out.reset(CObjectOStream::Open(m_Format, *stream));
  188. }
  189. template <class TRequest, class TReply>
  190. inline
  191. bool CRPCClient<TRequest, TReply>::x_ShouldRetry(unsigned int tries)
  192. {
  193.     _TRACE("CRPCClient<>::x_ShouldRetry: retrying after " << tries
  194.            << " failures");
  195.     return true;
  196. }
  197. END_NCBI_SCOPE
  198. /* @} */
  199. /*
  200. * ===========================================================================
  201. *
  202. * $Log: rpcbase.hpp,v $
  203. * Revision 1000.1  2004/04/12 17:15:36  gouriano
  204. * PRODUCTION: UPGRADED [CATCHUP_003] Dev-tree R1.5
  205. *
  206. * Revision 1.5  2004/03/16 19:41:41  gorelenk
  207. * Fixed errors inside implementation of
  208. * CRPCClient<TRequest, TReply>::SetTimeout .
  209. *
  210. * Revision 1.4  2003/12/16 20:55:32  dicuccio
  211. * Fixed compiler warning on MSVC - unreferenced exception variable removed
  212. *
  213. * Revision 1.3  2003/12/12 21:31:43  ucko
  214. * Support (configurably) retrying requests that run into I/O errors.
  215. * Partially doxygenize.
  216. *
  217. * Revision 1.2  2003/04/15 16:18:43  siyan
  218. * Added doxygen support
  219. *
  220. * Revision 1.1  2002/11/13 00:46:05  ucko
  221. * Add RPC client generator; CVS logs to end in generate.?pp
  222. *
  223. * ===========================================================================
  224. */
  225. #endif  /* SERIAL___RPCBASE__HPP */