02.Fabric源码解析---peer命令结构(王雅震)
Fabric源码解析2——peer命令结构
peer目录结构
peer目录结构自身十分清晰,一个main.go文件,其余文件夹除common,gossip外均为子命令集合,有chaincode,channel,clilogging,node,version五个,各司其职,供main.go整合使用。子命令文件夹中,与文件夹名称相同的.go文件为主要源码文件,其余的均为按功能划分的动作命令源码。
以node目录为例,node自身作为根命令的一个子命令,在node.go中实现,而node这个命令自身又有start,status,stop这三个动作去执行不同的任务,分别在对应start.go,status.go,stop.go中实现。注意,start,status,stop其实也是子命令,是node这个子命令的子命令,因为他们是在命令层级中最终去干活的底层的人,我觉得用动作去形容他们更贴切一些。
chaincode
channel
clilogging
common
gossip
node
node.go
start.go
status.go
stop.go
version
main.go
第三方包
在Getting Started中,无论是在启动peer容器时默认执行的命令,还是手工执行交易时在终端窗口所输入的命令,都类有类似的格式,如peer channel…,peer node…,peer chaincode…,这种 命令+子命令+选项 的风格,让人在感觉上毫无违和感。peer命令主要依赖第三方包github.com/spf13/cobra,由其组成基本的peer命令架构。所以在此简单介绍一下cobra。
cobra既是一个用于生成命令行程序的库,也是用来生成程序和命令文件的程序(即在命令行用cobra命令进行一系列操作,格式化生成一些使用cobra框架的源代码文件,用户可在此基础上进行编程)。目前,peer源码只将cobra当作一个库进行使用。cobra基本用法如下:
创建一个(根)命令对象,其原型为Command,每个命令都是一个Command对象实例。创建命令对象其实就是填充Command中的成员的过程罢了。需要注意的是,Command中的成员还有很多,其中有一批字段名为*Run,*RunE形式的成员,其作用与Run类似,区别在于运行的时间有先有后,是否被子命令继承,是否返回错误。
type Command struct { Use string //命令名称字段,如你在命令行敲的是peer ...,则该字段值就是"peer"Short string //短说明字段Long string //详细说明字段Run func(cmd *Command, args []string) //该命令所执行的函数...
}RootCmd := &cobra.Command{...}
如果有需要,对命令的添加flag,这一点可以简单的理解为命令选项。
RootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
如果有需要,对根命令添加子命令,子命令与根命令本质是一样的,只是人为的进行级别上的区分。
RootCmd.AddCommand(versionCmd)
运行命令
RootCmd.Execute()
由于文章重点在peer,所以在此只做简单介绍,更详细的使用方法,可在godoc或github.com/spf13/cobra上学习。其实阅读fabric源码过程中有一个感觉,就是项目的大神们选用的第三方库,一般都是既满足需求,又比较容易学习和上手。
peer命令结构解析
我们现在正式从peer/main.go文件开始解析源码,本文旨在解析peer的命令结构,因此只会涉及相关的源码,其他部分将会在其他主题文章中对应分析。如果你对cobra的用法稍微熟悉后,很容易就可以看懂main函数的构建。peer目录下的子命令的源码结构非常类似,也基本逃不出上文介绍的关于cobra的基本操作。
首先定义了一个mainCmd命令,var mainCmd =&cobra.Command{…},该命令填充了Use,PersistentPreRunE和Run成员。Use如我们预见的那样被赋值为peer,PersistentPreRunE先于Run执行,都被赋值了一个匿名函数。因为mainCmd只单纯作为根命令,不实现由子命令实现的具体的交易事务,因此实现的只是PersistentPreRunE指定的检查、初始化日志系统并缓存配置的功能,和Run指定的版本打印、命令帮助功能生成mainCmd对象的命令行标识对象mainFlags,mainFlags := mainCmd.PersistentFlags(),也就是peer命令的选项,并对该标识对像进行了维护,增加了version,logging_level两个选项。这也对应了其在自身对象中设置PersistentPreRunE和Run的功能。
首先定义了一个mainCmd命令,var mainCmd =,mainCmd.AddCommand(…)。添加的命令有
1. version.Cmd()
2. node.Cmd()
3. chaincode.Cmd(nil)
4. clilogging.Cmd(nil)
5. channel.Cmd(nil)
Cmd()是每个子命令文件中暴露出的函数,各自整合了各自的动作命令。
**启动根命令,mainCmd.Execute()。**启动了根命令,也就启动了其下的所有命令。子命令结构解析,以node为例其实读懂了peer命令,其余的子命令类推即可。在此还是啰嗦两句吧。上文已经说了子命令的源码结构是极其相似的,这里只以node为例。
**在node.go中,**首先定义了一个node命令对象,var nodeCmd = &cobra.Command{…}
**在Cmd函数中,**添加了startCmd(),statusCmd(),stopCmd()三个函数返回的start,status,stop子命令(动作命令),分别实现在start.go,status.go,stop.go。这三个命令的源码结构也是基本一致,在此仅以start和start.go为例。
在start.go中,首先定义了一个start命令对象,var nodeStartCmd = &cobra.Command{…},其中对RunE成员赋值了一个匿名函数,函数体中执行了serve函数,这也是该命令最终会调用的函数。serve函数是一个非常重要,非常复杂的函数。记不记得在上篇介绍Fabric项目线头的文章提到过的,在每个peer容器启动后默认执行的就是peer node start –peer-defaultchain=false命令,在此处就对接上了,该命令最终调用执行的就是serve函数,同时也就是说,serve函数会做了很多很多的准备工作。
02.Fabric源码解析---peer命令结构(王雅震)相关推荐
- 01.Fabric源码解析---线头(王雅震)
Fabric源码解析1--线头 Getting Started 简单提一下Fabric说明文档中的Getting Started部分.说明文档下载地址在 http://hyperledger-fabr ...
- btcd源码解析——peer节点之间的区块数据同步 (3) —— 非headersFirstMode模式
文章目录 1. 写在前面 2. 非headersFirstMode模式下的数据同步过程 2.1 peer A 发送"获取区块哈希"的请求 2.2 peer B 响应"获取 ...
- 链表node中保存的是什么_Redis源码解析一 --链表结构
Redis源码剖析-链表结构 1. redis中的链表 在redis中链表的应用非常广泛,例如列表键的底层实现之一就是链表.而且,在redis中的链表结构被实现成为双向链表,因此,在头部和尾部进行的操 ...
- Wayland 源码解析之代码结构
来源:http://blog.csdn.net/basilc/article/details/8074895 获取.编译 Wayland 及其依赖库可参考 Wayland 官方网站的 Build 指南 ...
- Redis源码解析(15) 哨兵机制[2] 信息同步与TILT模式
Redis源码解析(1) 动态字符串与链表 Redis源码解析(2) 字典与迭代器 Redis源码解析(3) 跳跃表 Redis源码解析(4) 整数集合 Redis源码解析(5) 压缩列表 Redis ...
- Block源码解析和深入理解
Block源码解析和深入理解 Block的本质 Block是"带有自动变量值的匿名函数". 我们通过Clang(LLVM编译器)来将OC的代码转换成C++源码的形式,通过如下命令: ...
- YOLOv3源码解析2-数据预处理Dataset()
YOLOv3源码解析1-代码整体结构 YOLOv3源码解析2-数据预处理Dataset() YOLOv3源码解析3-网络结构YOLOV3() YOLOv3源码解析4-计算损失compute_loss( ...
- 面试官系统精讲Java源码及大厂真题 - 02 String、Long 源码解析和面试题
02 String.Long 源码解析和面试题 劳动是一切知识的源泉. --陶铸 引导语 String 和 Long 大家都很熟悉,本小节主要结合实际的工作场景,来一起看下 String 和 Long ...
- Redis源码-String:Redis String命令、Redis String存储原理、Redis String三种编码类型、Redis字符串SDS源码解析、Redis String应用场景
Redis源码-String:Redis String命令.Redis String存储原理.Redis String三种编码类型.Redis字符串SDS源码解析.Redis String应用场景 R ...
- libev源码解析——监视器(watcher)结构和组织形式
在<libev源码解析--总览>中,我们介绍了libev的一些重要变量在不同编译参数下的定义位置.由于这些变量在多线程下没有同步问题,所以我们将问题简化,所提到的变量都是线程内部独有的,不 ...
最新文章
- micro hdmi引脚定义义_臻实力芯定义:京东AMD笔记本电脑双11开门红-AMD笔记本 ——快科技(驱动之家旗下媒体)-...
- 如何保证战略落地_战略如何规划落地?值得借鉴
- mysql innodb和myisam比较
- linux反序列化漏洞,思科多个产品Java反序列化漏洞(CVE-2015-6420)
- Linux Linux常用命令二
- Mnist数据集介绍
- 修改.class文件内容
- PDCA理念融入软件测试
- 人造肉在中国还有未来吗?
- mac MySql 重启
- (转)execute、executeQuery和executeUpdate之间的区别
- 拉格朗日插值法 【python】
- C语言布斯乘法算法,布斯Booth算法带符号位的乘法verilog语言实现booth算法
- 【vultr使用流程笔记】
- 手把手搭建SSM框架
- 腾达Tenda路由器中继wifi步骤
- 贵州学业水平计算机考试真题,贵州省2017年7月普通高中学业水平考试数学试卷(真题卷附全解析)...
- 一款全新的网页数据采集工具:爬山虎采集器
- 机器人学基础(一)——机器人几何结构分类及其自由度
- 2018年上半年总结
热门文章
- Python3,4行代码给图片加美颜,拍照再也不需要开美颜滤镜了。
- mono java 性能_Mono对Java的支持
- 为什么摇滚的人害羞_并非每个人都需要成为摇滚明星
- 如何给文件添加everyone权限
- 实现流程管理的五个步骤
- 帮你解决Kali Linux 外接无线网卡显示不出来的问题
- 居家生活|装修避免的坑
- 重庆2021年高考二诊成绩查询,2021年重庆二诊,2021年4月重庆二诊考试,重庆二诊康德卷...
- 计算机系统维护课程设计报告,计算机系统维护工程(第2版)
- 【Access2003】表的新建、用sql语句查询;关闭警告信息;修改数据库密码;修复数据库