steem 依賴插件的初始化和啟動(dòng)

在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宏用于將一個(gè)序列中參數(shù)依次按照指定宏進(jìn)行展開:

BOOST_PP_SEQ_FOR_EACH(macro, data, seq)

macro

一個(gè)以格式macro(r, data, elem)定義的三元宏。該宏被BOOST_PP_SEQ_FOR_EACH按照seq中每個(gè)元素進(jìn)行展開。展開該宏,需要用到下一個(gè)BOOST_PP_FOR的重復(fù)項(xiàng)、備用數(shù)據(jù)data和當(dāng)前元素。

data

備用數(shù)據(jù),用于傳給macro

seq

用于供macro按照哪個(gè)序列進(jìn)行展開

用法:

BOOST_PP_SEQ_FOR_EACH是一個(gè)重復(fù)項(xiàng)的宏。

如果序列是(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) ) 
}

繼續(xù)展開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)
}

繼續(xù)展開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是虛函數(shù),在抽象基類abstract_plugin中定義為接口,并在各個(gè)final插件中實(shí)現(xiàn),它負(fù)責(zé)注冊(cè)依賴的插件到application

回到database_api_plugin, 它依賴json_rpc_pluginchain_plugin,不僅需要把他們插件注冊(cè)到application,而且要在初始化和啟動(dòng)database_api_plugin插件的同時(shí),初始化和啟動(dòng)它的依賴插件json_rpc_pluginchain_plugin

初始化和啟動(dòng)database_api_plugin代碼如下:

//完全繼承自plugin<T>
virtual void initialize(const variables_map& options) override final
{
    if( _state == registered )
    {
        _state = initialized;
        //1:注冊(cè)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 );
        //注冊(cè)到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:注冊(cè)json_rpc_plugin和chain_plugin
        //2:啟動(dòng)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.") );
}

未避免重復(fù)初始化和啟動(dòng)插件,abstract_plugin定義了插件狀態(tài)

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
};
  • 當(dāng)且僅當(dāng)插件狀態(tài)為registered時(shí)才被執(zhí)行初始化
  • 當(dāng)且僅當(dāng)插件狀態(tài)為initialized時(shí)才被啟動(dòng)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 黃葉鋪成稿紙,金秋點(diǎn)染詩箋。 首首情詩說繾綣,隨風(fēng)落到江南。 把你讀成淚眼,將它畫到藍(lán)天。
    琴詩音閱讀 530評(píng)論 12 17
  • 魏老的病 "請(qǐng)問魏家怎么走?"沒有了江小冉的引領(lǐng),宋子陽只好邊走邊問。 "直走左拐一百米,再穿過一...
    晉軒姐姐閱讀 246評(píng)論 0 1
  • 因?yàn)槭强蛻粲喌乃詻]有拍詳細(xì)步驟圖(請(qǐng)勿私自保存發(fā)布) 多評(píng)價(jià),多意見,共進(jìn)步。
    F四木閱讀 487評(píng)論 2 5

友情鏈接更多精彩內(nèi)容