美文网首页
steem 依赖插件的初始化和启动

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

作者: jiongua | 来源:发表于2018-09-18 18:16 被阅读0次

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

    #define APPBASE_PLUGIN_REQUIRES_VISIT( r, visitor, elem ) \
      visitor( appbase::app().register_plugin<elem>() );
      
    #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<void(abstract_plugin&)> plugin_processor;
    virtual void plugin_for_each_dependency( plugin_processor&& l ) override 
    {  
          l( appbase::app().register_plugin<json_rpc_plugin>() );
          l( appbase::app().register_plugin<chain_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<T>
    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<T>
    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 依赖插件的初始化和启动

          本文链接:https://www.haomeiwen.com/subject/bclmnftx.html