steem 依赖插件的初始化和启动

在Plugin源码阅读过程中,遇到如下宏定义:

#define APPBASE_PLUGIN_REQUIRES_VISIT( r, visitor, elem ) \
  visitor( appbase::app().register_plugin() );
  
#define APPBASE_PLUGIN_REQUIRES( PLUGINS )                               \
   virtual void plugin_for_each_dependency( plugin_processor&& l ) override {  \
      BOOST_PP_SEQ_FOR_EACH( APPBASE_PLUGIN_REQUIRES_VISIT, l, PLUGINS ) \
   }

BOOST_PP_SEQ_FOR_EACH宏用于将一个序列中参数依次按照指定宏进行展开:

BOOST_PP_SEQ_FOR_EACH(macro, data, seq)

macro

一个以格式macro(r, data, elem)定义的三元宏。该宏被BOOST_PP_SEQ_FOR_EACH按照seq中每个元素进行展开。展开该宏,需要用到下一个BOOST_PP_FOR的重复项、备用数据data和当前元素。

data

备用数据,用于传给macro

seq

用于供macro按照哪个序列进行展开

用法:

BOOST_PP_SEQ_FOR_EACH是一个重复项的宏。

如果序列是(a)(b)(c),则展开为:

macro(r, data, a) macro(r, data, b) macro(r, data, c)

例如database_api_plugin类中定义了:

APPBASE_PLUGIN_REQUIRES(
         (gamebank::plugins::json_rpc::json_rpc_plugin)
         (gamebank::plugins::chain::chain_plugin)
      )

展开宏APPBASE_PLUGIN_REQUIRES

virtual void plugin_for_each_dependency( plugin_processor&& l ) override 
{  
      BOOST_PP_SEQ_FOR_EACH( APPBASE_PLUGIN_REQUIRES_VISIT, l, (json_rpc_plugin)(chain_plugin) ) 
}

继续展开BOOST_PP_SEQ_FOR_EACH

virtual void plugin_for_each_dependency( plugin_processor&& l ) override 
{  
      APPBASE_PLUGIN_REQUIRES_VISIT(r, l, json_rpc_plugin)
      APPBASE_PLUGIN_REQUIRES_VISIT(r, l, chain_plugin)
}

继续展开APPBASE_PLUGIN_REQUIRES_VISIT,最终得到:

//plugin_processor在class abstract_plugin中定义:
//typedef std::function plugin_processor;
virtual void plugin_for_each_dependency( plugin_processor&& l ) override 
{  
      l( appbase::app().register_plugin() );
      l( appbase::app().register_plugin() );
}

plugin_for_each_dependency是虚函数,在抽象基类abstract_plugin中定义为接口,并在各个final插件中实现,它负责注册依赖的插件到application

回到database_api_plugin, 它依赖json_rpc_pluginchain_plugin,不仅需要把他们插件注册到application,而且要在初始化和启动database_api_plugin插件的同时,初始化和启动它的依赖插件json_rpc_pluginchain_plugin

初始化和启动database_api_plugin代码如下:

//完全继承自plugin
virtual void initialize(const variables_map& options) override final
{
    if( _state == registered )
    {
        _state = initialized;
        //1:注册json_rpc_plugin和chain_plugin到database_api_plugin
        //2:初始化json_rpc_plugin和chain_plugin
        this->plugin_for_each_dependency( [&]( abstract_plugin& plug ){             plug.initialize( options ); } );
        //database_api_plugin::plugin_initialize()
        this->plugin_initialize( options );
        //注册到database_api_plugin到application
        app().plugin_initialized( *this );
    }
    if (_state != initialized)
        BOOST_THROW_EXCEPTION( std::runtime_error("Initial state was not registered, so final state cannot be initialized.") );
}
...
//完全继承自plugin
virtual void startup() override final
{
    if( _state == initialized )
    {
        _state = started;
        //1:注册json_rpc_plugin和chain_plugin
        //2:启动json_rpc_plugin和chain_plugin
        this->plugin_for_each_dependency( [&]( abstract_plugin& plug ){ plug.startup(); } );
         //database_api_plugin::plugin_startup
        this->plugin_startup();
        app().plugin_started( *this );
    }
    if (_state != started )
        BOOST_THROW_EXCEPTION( std::runtime_error("Initial state was not initialized, so final state cannot be started.") );
}

未避免重复初始化和启动插件,abstract_plugin定义了插件状态

enum state {
    registered, ///< the plugin is constructed but doesn't do anything
    initialized, ///< the plugin has initlaized any state required but is idle
    started, ///< the plugin is actively running
    stopped ///< the plugin is no longer running
};
  • 当且仅当插件状态为registered时才被执行初始化
  • 当且仅当插件状态为initialized时才被启动

你可能感兴趣的:(steem 依赖插件的初始化和启动)