6#include <boost/filesystem/path.hpp>
7#include <boost/core/demangle.hpp>
11 namespace bpo = boost::program_options;
98 template<
typename... Plugin>
125 return boost::any_cast<const T&>(
a) == boost::any_cast<const T&>(b);
135 template<
typename Plugin>
141 auto plug =
new Plugin();
142 plugins[plug->name()].reset(plug);
143 plug->register_dependencies();
147 template<
typename Plugin>
149 string name = boost::core::demangle(
typeid(Plugin).
name());
153 template<
typename Plugin>
166 template<
typename MethodDecl>
167 auto get_method() -> std::enable_if_t<is_method_decl<MethodDecl>::value,
typename MethodDecl::method_type&>
169 using method_type =
typename MethodDecl::method_type;
170 auto key = std::type_index(
typeid(MethodDecl));
171 auto itr = methods.find(key);
172 if(itr != methods.end()) {
173 return *method_type::get_method(itr->second);
175 methods.emplace(std::make_pair(key, method_type::make_unique()));
176 return *method_type::get_method(methods.at(key));
187 template<
typename ChannelDecl>
188 auto get_channel() -> std::enable_if_t<is_channel_decl<ChannelDecl>::value,
typename ChannelDecl::channel_type&>
190 using channel_type =
typename ChannelDecl::channel_type;
191 auto key = std::type_index(
typeid(ChannelDecl));
192 auto itr = channels.find(key);
193 if(itr != channels.end()) {
194 return *channel_type::get_channel(itr->second);
196 channels.emplace(std::make_pair(key, channel_type::make_unique()));
197 return *channel_type::get_channel(channels.at(key));
214 template <
typename Func>
216 return boost::asio::post(*io_serv, pri_queue.
wrap(
priority, std::forward<Func>(func)));
240 template<
typename Impl>
255 map<string, std::unique_ptr<abstract_plugin>> plugins;
256 vector<abstract_plugin*> initialized_plugins;
257 vector<abstract_plugin*> running_plugins;
259 std::function<void()> sighup_callback;
260 map<std::type_index, erased_method_ptr> methods;
261 map<std::type_index, erased_channel_ptr> channels;
263 std::shared_ptr<boost::asio::io_service> io_serv;
266 void start_sighup_handler( std::shared_ptr<boost::asio::signal_set> sighup_set );
267 void set_program_options();
269 void print_default_config(std::ostream&
os);
271 void wait_for_signal(std::shared_ptr<boost::asio::signal_set> ss);
272 void setup_signal_handling_on_ios(boost::asio::io_service& ios,
bool startup);
274 std::unique_ptr<class application_impl> my;
281 template<
typename Impl>
282 class plugin :
public abstract_plugin {
288 virtual const std::string&
name()
const override {
return _name; }
291 static_cast<Impl*
>(
this)->plugin_requires([&](
auto& plug){});
294 virtual void initialize(
const variables_map& options)
override {
297 static_cast<Impl*
>(
this)->plugin_requires([&](
auto& plug){ plug.initialize(options); });
298 static_cast<Impl*
>(
this)->plugin_initialize(options);
311 static_cast<Impl*
>(
this)->plugin_requires([&](
auto& plug){ plug.startup(); });
312 static_cast<Impl*
>(
this)->plugin_startup();
322 static_cast<Impl*
>(
this)->plugin_shutdown();
334 template<
typename Data,
typename DispatchPolicy>
336 if (has_subscribers()) {
@ stopped
the plugin is no longer running
@ started
the plugin is actively running
@ initialized
the plugin has initialized any state required but is idle
@ registered
the plugin is constructed but doesn't do anything
void plugin_initialized(abstract_plugin &plug)
const bpo::variables_map & get_options() const
void set_version_string(std::string v)
User provided version string for version_string() which overrides git describe value.
void set_version(uint64_t version)
Set version.
bool initialize(int argc, char **argv)
Looks for the –plugin commandline / config option and calls initialize on those plugins.
void set_default_config_dir(const bfs::path &config_dir="etc")
Set default config directory.
bfs::path data_dir() const
Get data directory.
bfs::path full_config_file_path() const
Get full config.ini path.
void register_config_type_comparison(std::type_index, config_comparison_f comp)
void set_sighup_callback(std::function< void()> callback)
Set function pointer invoked on receipt of SIGHUP.
auto post(int priority, Func &&func)
string version_string() const
Get version string; generated from git describe if available.
auto & get_priority_queue()
void set_thread_priority_max()
auto get_method() -> std::enable_if_t< is_method_decl< MethodDecl >::value, typename MethodDecl::method_type & >
boost::asio::io_service & get_io_service()
bfs::path get_logging_conf() const
Get logging configuration path.
bfs::path config_dir() const
Get config directory.
Plugin & get_plugin() const
void register_config_type()
string full_version_string() const
Get full version string; same as version_string() unless set differently.
static application & instance()
auto get_channel() -> std::enable_if_t< is_channel_decl< ChannelDecl >::value, typename ChannelDecl::channel_type & >
void plugin_started(abstract_plugin &plug)
Plugin * find_plugin() const
bool initialize_impl(int argc, char **argv, vector< abstract_plugin * > autostart_plugins)
uint64_t version() const
Get version.
void set_full_version_string(std::string v)
User provided full version string for full_version_string()
void set_default_data_dir(const bfs::path &data_dir="data-dir")
Set default data directory.
void publish(int priority, const Data &data)
boost::asio::executor_binder< Function, executor > wrap(int priority, Function &&func)
virtual void startup() override
virtual void shutdown() override
virtual const std::string & name() const override
plugin(const string &name)
virtual void register_dependencies()
virtual state get_state() const override
virtual void handle_sighup() override
virtual void initialize(const variables_map &options) override
std::function< bool(const boost::any &a, const boost::any &b)> config_comparison_f
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define T(meth, val, expected)
void write_default_config(const bfs::path &cfg_file, const options_description &cfg)
unsigned __int64 uint64_t