eos节点启动源码分析
在eos源码目录中programs/nodeos/main.cpp文件里,为节点启动的主函数
main函数内部做了两件事
1 初始化 application
if(!app().initialize<chain_plugin, http_plugin, net_plugin, producer_plugin>(argc, argv))
return INITIALIZE_FAIL;
2 application启动和插件启动
app().startup();
app().exec();
application类
先说application的基本实现和常用接口,application 定义了注册插件的函数,获取插件,查找插件等功能,根据模板动态绑定的
同样定义了一些私有函数和变量
application 构造函数为私有的,方便实现单例模式,plugins为存储各类注册插件的map,key为插件名,value为独占的基类指针,不可copy。
io_serv为boost库提供的io_service的shared_ptr,网络通信和事件注册派发会用到。initialized_plugins为已经初始化的插件vector,
running_plugins为已经runing的插件vector。
erased_method_ptr和erased_channel_ptr分别在method.hpp和channel.hpp中实现了定义,以后用到再分析。
application类protected部分包含三个函数
initialize_impl 根据配置初始化插件。
plugin_initialized 将插件放入初始化vector
plugin_started 将插件放入runing vector
下面是application实现的单例模式,定义全局函数app(),内部调用application类静态函数instance()
application的start函数内部调用了各个插件的startup,出现异常shutdown
exec()内部注册了SIGINT,SIGTERM,SIGPIPE信号,当进程收到这几个信号会导致ioservice->stop(),否则io_ser->run()一直监听等待就绪事件
plugin类
abstract_plugin为所有插件继承的纯虚类,不同插件会实现各自特有的功能
plugin.hpp中定义了
BOOST_PP_SEQ_FOR_EACH为boost定义的宏,按照参数PLUGINS依次展开,将lambda函数l和每个PLUGIN传入
APPBASE_PLUGIN_REQUIRES_VISIT,比如net_api_plugin展开
展开后
void plugin_requires( Lambda&& l ) {
l(appbase::app().register_plugin<net_plugin>())
l(appbase::app().register_plugin<http_plugin>())
}
就是采用注册的lambda表达式依次调用,并且将各个插件注册到application中。
plugin 继承了abstract_plugin类
Impl是模板类型,不同的插件会传入不同的模板类型,initialize,startup,shutdown为虚函数,重写了基类abstract_plugin的功能。内部通过
static_cast<Impl*>(this)转化为对应的不同模板类型的plugin,进而实现特定功能的绑定,初始化,启动,停止等。举例:
net_plugin 继承了plugin,并且模板类型为net_plugin,这样当plugin<net_plugin>调用initialize、startup、shutdown、函数,内部展开如下:
static_cast<net_plugin*>(this)->plugin_requires([&](auto& plug){ plug.initialize(options); });
static_cast<net_plugin*>(this)->plugin_initialize(options);
static_cast<net_plugin*>(this)->plugin_startup();
static_cast<net_plugin*>(this)->plugin_shutdown();
APPBASE_PLUGIN_REQUIRES((chain_plugin))展开
void plugin_requires( Lambda&& l ) {
l(appbase::app().register_plugin<chain_plugin>()
}
所以static_cast<net_plugin*>(this)->plugin_requires(&{ plug.initialize(options); });
实际继续展开内部调用appbase::app().register_plugin<chain_plugin>().initialize(options);完成网络部分的初始化。
startup,shutdown也是一样的道理。
谢谢关注我的公众号
eos节点启动源码分析的更多相关文章
- RocketMQ中Broker的启动源码分析(一)
在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...
- RocketMQ中Broker的启动源码分析(二)
接着上一篇博客 [RocketMQ中Broker的启动源码分析(一)] 在完成准备工作后,调用start方法: public static BrokerController start(Broker ...
- RocketMQ中PullConsumer的启动源码分析
通过DefaultMQPullConsumer作为默认实现,这里的启动过程和Producer很相似,但相比复杂一些 [RocketMQ中Producer的启动源码分析] DefaultMQPullCo ...
- Django如何启动源码分析
Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...
- Netty源码分析 (三)----- 服务端启动源码分析
本文接着前两篇文章来讲,主要讲服务端类剩下的部分,我们还是来先看看服务端的代码 /** * Created by chenhao on 2019/9/4. */ public final class ...
- 【Netty之旅四】你一定看得懂的Netty客户端启动源码分析!
前言 前面小飞已经讲解了NIO和Netty服务端启动,这一讲是Client的启动过程. 源码系列的文章依旧还是遵循大白话+画图的风格来讲解,本文Netty源码及以后的文章版本都基于:4.1.22.Fi ...
- Quartz源码——scheduler.start()启动源码分析(二)
scheduler.start()是Quartz的启动方式!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! Quar ...
- Seata AT 模式启动源码分析
从上一篇文章「分布式事务中间件Seata的设计原理」讲了下 Seata AT 模式的一些设计原理,从中也知道了 AT 模式的三个角色(RM.TM.TC),接下来我会更新 Seata 源码分析系列文章. ...
- Netty服务端的启动源码分析
ServerBootstrap的构造: public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Serve ...
随机推荐
- MiZ702学习笔记11——如何使用vivado isim仿真
说到vivado的仿真确实是很有意思,不管是ISE还是Quartus都可以自己自动生成测试平台的完整构架,但是vivado不行,所有的测试代码自己写!(我反正是查了好久,都没发现vivado如何自动生 ...
- DotNetCore部署(IIS)踩坑记
一.windows系统中Dotnet core runtime 安装后,无法启动次程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll的解决方法 错误现象如图 因为 ...
- 12、利用docker快速搭建Wordpress网站
一.准备工作 结构图: 用户访问页面,Nginx将请求进行转发,如果请求的是php页面,则通过FastCGI转发给后端php进行处理:如果非php页面,则直接返回静态页面. 关键点: mysql.ph ...
- Synchronous/Asynchronous:任务的同步异步,以及asynchronous callback异步回调
两个线程执行任务有同步和异步之分,看了Quora上的一些问答有了更深的认识. When you execute something synchronously, you wait for it to ...
- Katalon Studio学习笔记(二)——请求响应中文乱码解决方法
Katalon Studio接口测试发现返回的中文消息是乱码,这是因为KS的编码格式是UTF-8,因此导致中文字体出现乱码.如下图所示: 在我们的系统中添加一个名字为JAVA_TOOL_OPTIONS ...
- unity小地图制作___按比例尺图标布局
1. 2.这里小地图显示的范围为整个空间区域,而不是单独的相机渲染区域 3. 4. 5. using System.Collections; using System.Collections.Gene ...
- 无前趋的顶点优先的拓扑排序方法(JAVA)(转载http://128kj.iteye.com/blog/1706968)
无前趋的顶点优先的拓扑排序方法 该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为: NonPreFirstTopSort(G){//优先输出无前趋的顶点 w ...
- @JsonFormat时间格式化注解使用
@JsonFormat注解是一个时间格式化注解,比如我们存储在mysql中的数据是date类型的,当我们读取出来封装在实体类中的时候,就会变成英文时间格式,而不是yyyy-MM-dd HH:mm:ss ...
- hadoop-lzo 安装配置
在hive中要想使用lzo的格式,需要配置安装好lzo工具并且在hadoop的core-site.xml与mapred-site.xml中配置相应的配置 一.编译安装lzo与lzop 在 ...
- [!] CocoaPods could not find compatible versions for pod "Folly"问题举例
$ pod install 后出现下面错误: [!] CocoaPods could not find compatible versions for pod "Folly": I ...