GNU Radio Manual and C++ API Reference  3.8.0.0
The Free & Open Software Radio Ecosystem
thrift_application_base.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2015 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef THRIFT_APPLICATION_BASE_H
24 #define THRIFT_APPLICATION_BASE_H
25 
26 #include <gnuradio/api.h>
27 #include <gnuradio/logger.h>
28 #include <gnuradio/prefs.h>
29 #include <gnuradio/thread/thread.h>
30 #include <boost/date_time/posix_time/posix_time.hpp>
31 #include <boost/scoped_ptr.hpp>
32 
33 namespace {
34 // Time, in milliseconds, to wait between checks to the Thrift runtime to see if
35 // it has fully initialized.
36 static const unsigned int THRIFTAPPLICATION_ACTIVATION_TIMEOUT_MS(200);
37 }; // namespace
38 
39 namespace apache {
40 namespace thrift {
41 namespace server {
42 class TServer;
43 }
44 } // namespace thrift
45 } // namespace apache
46 
47 /*!
48  * \brief Class to be statically initialized by thrift_application_base. Used
49  * to store state for thrift_application_base's singleton functions.
50  */
51 
53 {
54 public:
57  {
58  ;
59  }
60 
61  // Used to ensure the Thrift runtime is initialized on the first call to ::i().
63  // Stores the generated endpoint string after the Thrift runtime has initialized.
64  std::string d_endpointStr;
65  // Thread to execute the Thrift runtime's blocking serve() function.
66  boost::shared_ptr<gr::thread::thread> d_start_thrift_thread;
67 };
68 
69 /*!
70  * \brief Base class for a Thrift application with a singleton with
71  * instance function thrift_application_base::i(). Lazy initialization
72  * is used to start the Thrift runtime, therefore the Thrift runtime
73  * is not started unless thrift_application_base::i() is called at
74  * least once. This typically means that at least one rpc variable
75  * must be registered by a block before the runtime will start.
76  *
77  * \param TserverBase Template parameter naming the type of the server
78  * base, which is typically rpcserverbase.
79  * \param TserverClass Template parameter naming the eventual type of
80  * the fully derived application.
81  * \param _app Reference to the fully derived application instance to
82  * be returned by thrift_application_base::i().
83  */
84 
85 template <typename TserverBase, typename TserverClass>
87 {
88 public:
89  thrift_application_base(TserverClass* _app);
90 
91  /*!
92  * Destructor for the application. Since shutdown and cleanup of the
93  * runtime is typically custom to a particular booter
94  * implementation, this must be implemented as a specialized function
95  * for a particular booter. Thus a template implementation is not
96  * provided here.
97  */
99 
100  /*!
101  * The application singleton instance function.
102  */
103  static TserverBase* i();
104 
105  /*!
106  * Returns the endpoint string of this application.
107  */
108  static const std::vector<std::string> endpoints();
109 
110 protected:
111  /*!
112  * Allows this application's booter to set the endpoint string after
113  * the Thrift runtime has initialized.
114  *
115  * \param[in] endpoint The endpoint string reported by this class.
116  */
117  void set_endpoint(const std::string& endpoint);
118 
119  virtual TserverBase* i_impl() = 0;
120 
121  /*!
122  * Reference to the fully derived application instance.
123  */
124  static TserverClass* d_application;
125 
126  /*!
127  * Reference to the Thrift runtime.
128  */
129  boost::scoped_ptr<apache::thrift::server::TServer> d_thriftserver;
130 
131  /*!
132  * Max number of attempts when checking the Thrift runtime for
133  * Initialization before giving up. Set in the Thrift config file
134  * (see \ref ctrlport_thrift_prefs).
135  */
136  static const unsigned int d_default_max_init_attempts;
137 
138  /*!
139  * Default port for the runtime to listen on, if a static port is
140  * not specified. Set in the Thrift config file (see \ref
141  * ctrlport_thrift_prefs).
142  */
143  static const unsigned int d_default_thrift_port;
144 
145  /*!
146  * Maximum number of threads to create when serving multiple rpc
147  * clients. Set in the Thrift config file (see \ref
148  * ctrlport_thrift_prefs).
149  */
150  static const unsigned int d_default_num_thrift_threads;
151 
152  /*!
153  * Default packet size for the IP payload of thrift packets. Set in
154  * the Thrift config file (see \ref ctrlport_thrift_prefs).
155  */
156  static const unsigned int d_default_thrift_buffer_size;
157 
158  /*!
159  * \ref page_logger instances.
160  */
162 
163 private:
164  // Function to be called in a separate thread to invoke the blocking
165  // ThriftServer::serve() function. Must be specialized for a particular
166  // booter implementation, therefore a template implementation is
167  // not provided here.
168  void start_thrift();
169 
170  // Non-blocking function that returns true when the Thrift
171  // runtime has finished initialization. Must be implemented
172  // as a specialized template function for a particular booter
173  // implementation, therefore template implementation is not
174  // provided here.
175  bool application_started();
176 
177  // Internal function to start the initialization of the runtime.
178  // Since this singleton uses lazy instantiation, this function
179  // will be called on the first call to the instance function ::i(),
180  // and since ::i() is static, this function must be static as well.
181  static void start_application();
182 
183  // Pointer to the structure containing statically allocated
184  // state information for the applicaiton_base singleton.
185  static boost::scoped_ptr<thrift_application_base_impl> p_impl;
186 
187  // Mutex to protect the endpoint string.
188  gr::thread::mutex d_lock;
189 
190  // Will be set to true by a the application_started() function,
191  // specialized for a particular booter implementation, once the
192  // thrift runtime has successfully initialized.
193  bool d_thirft_is_running;
194 };
195 
196 template <typename TserverBase, typename TserverClass>
198 
199 template <typename TserverBase, typename TserverClass>
201  TserverClass* _app)
202  : d_lock(), d_thirft_is_running(false)
203 {
205  d_application = _app;
206 }
207 
208 template <typename TserverBase, typename TserverClass>
210 {
211  unsigned int max_init_attempts =
212  static_cast<unsigned int>(gr::prefs::singleton()->get_long(
213  "thrift", "init_attempts", d_default_max_init_attempts));
214 
215  if (!p_impl->d_application_initilized) {
216  p_impl->d_start_thrift_thread.reset((new gr::thread::thread(
217  boost::bind(&thrift_application_base::start_thrift, d_application))));
218 
219  bool app_started(false);
220  for (unsigned int attempts(0); (!app_started && attempts < max_init_attempts);
221  ++attempts) {
222  boost::this_thread::sleep(
223  boost::posix_time::milliseconds(THRIFTAPPLICATION_ACTIVATION_TIMEOUT_MS));
224  app_started = d_application->application_started();
225  }
226 
227  if (!app_started) {
228  GR_WARN("thrift_application_base",
229  "thrift_application_base::start_application(), "
230  "timeout waiting to port number might have failed?");
231  }
232 
233  p_impl->d_application_initilized = true;
234  }
235 }
236 
237 template <typename TserverBase, typename TserverClass>
238 const std::vector<std::string>
240 {
241  std::vector<std::string> ep;
242  ep.push_back(p_impl->d_endpointStr);
243  return ep;
244 }
245 
246 template <typename TserverBase, typename TserverClass>
248  const std::string& endpoint)
249 {
250  gr::thread::scoped_lock guard(d_lock);
251  p_impl->d_endpointStr = endpoint;
252 }
253 
254 template <typename TserverBase, typename TserverClass>
256 {
257  if (!p_impl->d_application_initilized) {
258  start_application();
259  }
260  return d_application->i_impl();
261 }
262 
263 #endif
boost::unique_lock< boost::mutex > scoped_lock
Definition: thread.h:49
gr::logger_ptr d_logger
Definition: thrift_application_base.h:161
std::string d_endpointStr
Definition: thrift_application_base.h:64
static const unsigned int d_default_max_init_attempts
Definition: thrift_application_base.h:136
static const std::vector< std::string > endpoints()
Definition: thrift_application_base.h:239
static TserverClass * d_application
Definition: thrift_application_base.h:124
static const unsigned int d_default_num_thrift_threads
Definition: thrift_application_base.h:150
boost::thread thread
Definition: thread.h:47
static TserverBase * i()
Definition: thrift_application_base.h:255
virtual long get_long(const std::string &section, const std::string &option, long default_val)
If option exists and value can be converted to long, return it; else default_val. ...
boost::scoped_ptr< apache::thrift::server::TServer > d_thriftserver
Definition: thrift_application_base.h:129
Base class for a Thrift application with a singleton with instance function thrift_application_base::...
Definition: thrift_application_base.h:86
GR_RUNTIME_API bool configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d, const std::string name)
#define GR_WARN(name, msg)
Definition: logger.h:188
Class to be statically initialized by thrift_application_base. Used to store state for thrift_applica...
Definition: thrift_application_base.h:52
thrift_application_base(TserverClass *_app)
Definition: thrift_application_base.h:200
Definition: thrift_application_base.h:39
virtual TserverBase * i_impl()=0
static const unsigned int d_default_thrift_port
Definition: thrift_application_base.h:143
log4cpp::Category * logger_ptr
GR_LOG macrosThese macros wrap the standard LOG4CPP_LEVEL macros. The availablie macros are: LOG_DEBU...
Definition: logger.h:71
bool d_application_initilized
Definition: thrift_application_base.h:62
boost::mutex mutex
Definition: thread.h:48
static prefs * singleton()
thrift_application_base_impl()
Definition: thrift_application_base.h:55
boost::shared_ptr< gr::thread::thread > d_start_thrift_thread
Definition: thrift_application_base.h:66
static const unsigned int d_default_thrift_buffer_size
Definition: thrift_application_base.h:156
gr::logger_ptr d_debug_logger
Definition: thrift_application_base.h:161
void set_endpoint(const std::string &endpoint)
Definition: thrift_application_base.h:247