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命令结构(王雅震)相关推荐

  1. 01.Fabric源码解析---线头(王雅震)

    Fabric源码解析1--线头 Getting Started 简单提一下Fabric说明文档中的Getting Started部分.说明文档下载地址在 http://hyperledger-fabr ...

  2. btcd源码解析——peer节点之间的区块数据同步 (3) —— 非headersFirstMode模式

    文章目录 1. 写在前面 2. 非headersFirstMode模式下的数据同步过程 2.1 peer A 发送"获取区块哈希"的请求 2.2 peer B 响应"获取 ...

  3. 链表node中保存的是什么_Redis源码解析一 --链表结构

    Redis源码剖析-链表结构 1. redis中的链表 在redis中链表的应用非常广泛,例如列表键的底层实现之一就是链表.而且,在redis中的链表结构被实现成为双向链表,因此,在头部和尾部进行的操 ...

  4. Wayland 源码解析之代码结构

    来源:http://blog.csdn.net/basilc/article/details/8074895 获取.编译 Wayland 及其依赖库可参考 Wayland 官方网站的 Build 指南 ...

  5. Redis源码解析(15) 哨兵机制[2] 信息同步与TILT模式

    Redis源码解析(1) 动态字符串与链表 Redis源码解析(2) 字典与迭代器 Redis源码解析(3) 跳跃表 Redis源码解析(4) 整数集合 Redis源码解析(5) 压缩列表 Redis ...

  6. Block源码解析和深入理解

    Block源码解析和深入理解 Block的本质 Block是"带有自动变量值的匿名函数". 我们通过Clang(LLVM编译器)来将OC的代码转换成C++源码的形式,通过如下命令: ...

  7. YOLOv3源码解析2-数据预处理Dataset()

    YOLOv3源码解析1-代码整体结构 YOLOv3源码解析2-数据预处理Dataset() YOLOv3源码解析3-网络结构YOLOV3() YOLOv3源码解析4-计算损失compute_loss( ...

  8. 面试官系统精讲Java源码及大厂真题 - 02 String、Long 源码解析和面试题

    02 String.Long 源码解析和面试题 劳动是一切知识的源泉. --陶铸 引导语 String 和 Long 大家都很熟悉,本小节主要结合实际的工作场景,来一起看下 String 和 Long ...

  9. 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 ...

  10. libev源码解析——监视器(watcher)结构和组织形式

    在<libev源码解析--总览>中,我们介绍了libev的一些重要变量在不同编译参数下的定义位置.由于这些变量在多线程下没有同步问题,所以我们将问题简化,所提到的变量都是线程内部独有的,不 ...

最新文章

  1. micro hdmi引脚定义义_臻实力芯定义:京东AMD笔记本电脑双11开门红-AMD笔记本 ——快科技(驱动之家旗下媒体)-...
  2. 如何保证战略落地_战略如何规划落地?值得借鉴
  3. mysql innodb和myisam比较
  4. linux反序列化漏洞,思科多个产品Java反序列化漏洞(CVE-2015-6420)
  5. Linux Linux常用命令二
  6. Mnist数据集介绍
  7. 修改.class文件内容
  8. PDCA理念融入软件测试
  9. 人造肉在中国还有未来吗?
  10. mac MySql 重启
  11. (转)execute、executeQuery和executeUpdate之间的区别
  12. 拉格朗日插值法 【python】
  13. C语言布斯乘法算法,布斯Booth算法带符号位的乘法verilog语言实现booth算法
  14. 【vultr使用流程笔记】
  15. 手把手搭建SSM框架
  16. 腾达Tenda路由器中继wifi步骤
  17. 贵州学业水平计算机考试真题,贵州省2017年7月普通高中学业水平考试数学试卷(真题卷附全解析)...
  18. 一款全新的网页数据采集工具:爬山虎采集器
  19. 机器人学基础(一)——机器人几何结构分类及其自由度
  20. 2018年上半年总结

热门文章

  1. Python3,4行代码给图片加美颜,拍照再也不需要开美颜滤镜了。
  2. mono java 性能_Mono对Java的支持
  3. 为什么摇滚的人害羞_并非每个人都需要成为摇滚明星
  4. 如何给文件添加everyone权限
  5. 实现流程管理的五个步骤
  6. 帮你解决Kali Linux 外接无线网卡显示不出来的问题
  7. 居家生活|装修避免的坑
  8. 重庆2021年高考二诊成绩查询,2021年重庆二诊,2021年4月重庆二诊考试,重庆二诊康德卷...
  9. 计算机系统维护课程设计报告,计算机系统维护工程(第2版)
  10. 【Access2003】表的新建、用sql语句查询;关闭警告信息;修改数据库密码;修复数据库