美文网首页
EOS应用程序框架appbase

EOS应用程序框架appbase

作者: vergil6 | 来源:发表于2018-10-23 17:24 被阅读38次

    简介

    EOS中的cleos,nodeos,keosd都是基于插件的应用程序框架appbase构建的,appbase库提供了一个从一组插件构建应用程序的基本框架, appbase管理插件生命周期并确保所有插件以正确的顺序配置,初始化,启动和关闭,appbase使用boost::asio作为异步库,目前是单线程单实例可以通过appbase :: app()访问这个单例,appbase给插件提供了插件之间的通信接口channel和method, 使插件的之间的通信耦合性更加低

    示例

    可以在appbase/examples目录中找到基于插件应用程序的简单示例。下面给出一个有2个插件的简单例子

    #include <appbase/application.hpp>
    #include <iostream>
    #include <boost/exception/diagnostic_information.hpp>
    
    struct database { };
    
    namespace bpo = boost::program_options;
    
    using bpo::options_description;
    using bpo::variables_map;
    using std::string;
    using std::vector;
    
    
    class chain_plugin : public appbase::plugin<chain_plugin>
    {
       public:
         APPBASE_PLUGIN_REQUIRES();
    
          // 设置命令行选项参数
         virtual void set_program_options( options_description& cli, options_description& cfg ) override
         {
             cfg.add_options()
                   ("readonly", "open the database in read only mode")
                   ("dbsize", bpo::value<uint64_t>()->default_value( 8*1024 ), "Minimum size MB of database shared memory file")
                   ;
             cli.add_options()
                   ("replay", "clear chain database and replay all blocks" )
                   ("reset", "clear chain database and block log" )
                   ;
         }
            
          // 插件的初始化
         void plugin_initialize( const variables_map& options ) { std::cout << "initialize chain plugin\n"; }
          // 插件的启动
         void plugin_startup()  { std::cout << "starting chain plugin \n"; }
          // 插件的关闭
         void plugin_shutdown() { std::cout << "shutdown chain plugin \n"; }
    };
    
    class net_plugin : public appbase::plugin<net_plugin>
    {
       public:
         net_plugin(){};
         ~net_plugin(){};
    
         APPBASE_PLUGIN_REQUIRES( (chain_plugin) );
    
         virtual void set_program_options( options_description& cli, options_description& cfg ) override
         {
            cfg.add_options()
                  ("listen-endpoint", bpo::value<string>()->default_value( "127.0.0.1:9876" ), "The local IP address and port to listen for incoming connections.")
                  ("remote-endpoint", bpo::value< vector<string> >()->composing(), "The IP address and port of a remote peer to sync with.")
                  ("public-endpoint", bpo::value<string>()->default_value( "0.0.0.0:9876" ), "The public IP address and port that should be advertized to peers.")
                  ;
         }
    
         void plugin_initialize( const variables_map& options ) { std::cout << "initialize net plugin\n"; }
         void plugin_startup()  { std::cout << "starting net plugin \n"; }
         void plugin_shutdown() { std::cout << "shutdown net plugin \n"; }
    
    };
    // 注册插件
    static appbase::abstract_plugin& _producer_plugin = appbase::app().register_plugin<chain_plugin>();
    // 注册插件
    static appbase::abstract_plugin& _producer_plugin2 = appbase::app().register_plugin<net_plugin>();
    
    
    int main( int argc, char** argv ) {
       try {
          // 需要加载的插件
          if( !appbase::app().initialize<chain_plugin, net_plugin>( argc, argv ) )
             return -1;
          // 启动所有加载的插件
          appbase::app().startup();
          // 注册信号,io_service.run()进入事件循环
          appbase::app().exec();
       } catch ( const boost::exception& e ) {
          std::cerr << boost::diagnostic_information(e) << "\n";
       } catch ( const std::exception& e ) {
          std::cerr << e.what() << "\n";
       } catch ( ... ) {
          std::cerr << "unknown exception\n";
       }
       std::cout << "exited cleanly\n";
       return 0;
    }
    

    执行之后的结果:

    ~/code/eos/build/libraries/appbase/examples$ ./appbase_example 
    initialize chain plugin
    initialize net plugin
    starting chain plugin 
    starting net plugin 
    ^Cshutdown net plugin 
    shutdown chain plugin 
    exited cleanly
    

    main函数中启动一个基于appbase程序必须的3步:
    1)appbase::app().initialize<plugin_name1,plugin_name2 ...>( argc, argv ) ,加载需要的插件,注意这些plugin_name必须是已经注册的,程序可以选择性的加载已注册的需要的插件
    2)appbase::app().startup(),启动所有加载的插件
    3)注册信号(SIGINT,SIGTERM,SIGPIPE),io_service.run()进入事件循环

    相关文章

      网友评论

          本文标题:EOS应用程序框架appbase

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