02.Fabric源码解析---peer命令结构(王雅震)
Fabric源碼解析2——peer命令結(jié)構(gòu)
peer目錄結(jié)構(gòu)
peer目錄結(jié)構(gòu)自身十分清晰,一個(gè)main.go文件,其余文件夾除common,gossip外均為子命令集合,有chaincode,channel,clilogging,node,version五個(gè),各司其職,供main.go整合使用。子命令文件夾中,與文件夾名稱相同的.go文件為主要源碼文件,其余的均為按功能劃分的動(dòng)作命令源碼。
以node目錄為例,node自身作為根命令的一個(gè)子命令,在node.go中實(shí)現(xiàn),而node這個(gè)命令自身又有start,status,stop這三個(gè)動(dòng)作去執(zhí)行不同的任務(wù),分別在對(duì)應(yīng)start.go,status.go,stop.go中實(shí)現(xiàn)。注意,start,status,stop其實(shí)也是子命令,是node這個(gè)子命令的子命令,因?yàn)樗麄兪窃诿顚蛹?jí)中最終去干活的底層的人,我覺得用動(dòng)作去形容他們更貼切一些。
chaincode channel clilogging common gossip node node.go start.go status.go stop.go version main.go第三方包
在Getting Started中,無論是在啟動(dòng)peer容器時(shí)默認(rèn)執(zhí)行的命令,還是手工執(zhí)行交易時(shí)在終端窗口所輸入的命令,都類有類似的格式,如peer channel…,peer node…,peer chaincode…,這種 命令+子命令+選項(xiàng) 的風(fēng)格,讓人在感覺上毫無違和感。peer命令主要依賴第三方包github.com/spf13/cobra,由其組成基本的peer命令架構(gòu)。所以在此簡(jiǎn)單介紹一下cobra。
cobra既是一個(gè)用于生成命令行程序的庫(kù),也是用來生成程序和命令文件的程序(即在命令行用cobra命令進(jìn)行一系列操作,格式化生成一些使用cobra框架的源代碼文件,用戶可在此基礎(chǔ)上進(jìn)行編程)。目前,peer源碼只將cobra當(dāng)作一個(gè)庫(kù)進(jìn)行使用。cobra基本用法如下:
創(chuàng)建一個(gè)(根)命令對(duì)象,其原型為Command,每個(gè)命令都是一個(gè)Command對(duì)象實(shí)例。創(chuàng)建命令對(duì)象其實(shí)就是填充Command中的成員的過程罷了。需要注意的是,Command中的成員還有很多,其中有一批字段名為*Run,*RunE形式的成員,其作用與Run類似,區(qū)別在于運(yùn)行的時(shí)間有先有后,是否被子命令繼承,是否返回錯(cuò)誤。
type Command struct { Use string //命令名稱字段,如你在命令行敲的是peer ...,則該字段值就是"peer"Short string //短說明字段Long string //詳細(xì)說明字段Run func(cmd *Command, args []string) //該命令所執(zhí)行的函數(shù)... }RootCmd := &cobra.Command{...}如果有需要,對(duì)命令的添加flag,這一點(diǎn)可以簡(jiǎn)單的理解為命令選項(xiàng)。
RootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")如果有需要,對(duì)根命令添加子命令,子命令與根命令本質(zhì)是一樣的,只是人為的進(jìn)行級(jí)別上的區(qū)分。
RootCmd.AddCommand(versionCmd)運(yùn)行命令
RootCmd.Execute()
由于文章重點(diǎn)在peer,所以在此只做簡(jiǎn)單介紹,更詳細(xì)的使用方法,可在godoc或github.com/spf13/cobra上學(xué)習(xí)。其實(shí)閱讀fabric源碼過程中有一個(gè)感覺,就是項(xiàng)目的大神們選用的第三方庫(kù),一般都是既滿足需求,又比較容易學(xué)習(xí)和上手。
peer命令結(jié)構(gòu)解析
我們現(xiàn)在正式從peer/main.go文件開始解析源碼,本文旨在解析peer的命令結(jié)構(gòu),因此只會(huì)涉及相關(guān)的源碼,其他部分將會(huì)在其他主題文章中對(duì)應(yīng)分析。如果你對(duì)cobra的用法稍微熟悉后,很容易就可以看懂main函數(shù)的構(gòu)建。peer目錄下的子命令的源碼結(jié)構(gòu)非常類似,也基本逃不出上文介紹的關(guān)于cobra的基本操作。
首先定義了一個(gè)mainCmd命令,var mainCmd =&cobra.Command{…},該命令填充了Use,PersistentPreRunE和Run成員。Use如我們預(yù)見的那樣被賦值為peer,PersistentPreRunE先于Run執(zhí)行,都被賦值了一個(gè)匿名函數(shù)。因?yàn)閙ainCmd只單純作為根命令,不實(shí)現(xiàn)由子命令實(shí)現(xiàn)的具體的交易事務(wù),因此實(shí)現(xiàn)的只是PersistentPreRunE指定的檢查、初始化日志系統(tǒng)并緩存配置的功能,和Run指定的版本打印、命令幫助功能生成mainCmd對(duì)象的命令行標(biāo)識(shí)對(duì)象mainFlags,mainFlags := mainCmd.PersistentFlags(),也就是peer命令的選項(xiàng),并對(duì)該標(biāo)識(shí)對(duì)像進(jìn)行了維護(hù),增加了version,logging_level兩個(gè)選項(xiàng)。這也對(duì)應(yīng)了其在自身對(duì)象中設(shè)置PersistentPreRunE和Run的功能。
首先定義了一個(gè)mainCmd命令,var mainCmd =,mainCmd.AddCommand(…)。添加的命令有
1. version.Cmd() 2. node.Cmd() 3. chaincode.Cmd(nil) 4. clilogging.Cmd(nil) 5. channel.Cmd(nil)Cmd()是每個(gè)子命令文件中暴露出的函數(shù),各自整合了各自的動(dòng)作命令。
**啟動(dòng)根命令,mainCmd.Execute()。**啟動(dòng)了根命令,也就啟動(dòng)了其下的所有命令。子命令結(jié)構(gòu)解析,以node為例其實(shí)讀懂了peer命令,其余的子命令類推即可。在此還是啰嗦兩句吧。上文已經(jīng)說了子命令的源碼結(jié)構(gòu)是極其相似的,這里只以node為例。
**在node.go中,**首先定義了一個(gè)node命令對(duì)象,var nodeCmd = &cobra.Command{…}
**在Cmd函數(shù)中,**添加了startCmd(),statusCmd(),stopCmd()三個(gè)函數(shù)返回的start,status,stop子命令(動(dòng)作命令),分別實(shí)現(xiàn)在start.go,status.go,stop.go。這三個(gè)命令的源碼結(jié)構(gòu)也是基本一致,在此僅以start和start.go為例。
在start.go中,首先定義了一個(gè)start命令對(duì)象,var nodeStartCmd = &cobra.Command{…},其中對(duì)RunE成員賦值了一個(gè)匿名函數(shù),函數(shù)體中執(zhí)行了serve函數(shù),這也是該命令最終會(huì)調(diào)用的函數(shù)。serve函數(shù)是一個(gè)非常重要,非常復(fù)雜的函數(shù)。記不記得在上篇介紹Fabric項(xiàng)目線頭的文章提到過的,在每個(gè)peer容器啟動(dòng)后默認(rèn)執(zhí)行的就是peer node start –peer-defaultchain=false命令,在此處就對(duì)接上了,該命令最終調(diào)用執(zhí)行的就是serve函數(shù),同時(shí)也就是說,serve函數(shù)會(huì)做了很多很多的準(zhǔn)備工作。
總結(jié)
以上是生活随笔為你收集整理的02.Fabric源码解析---peer命令结构(王雅震)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网页title图标设置
- 下一篇: Java中Long和long的区别