- Docker源碼分析
- 孫宏亮
- 613字
- 2018-12-31 20:27:05
3.3.3 創建engine對象
在mainDaemon()運行過程中,flag參數檢查完畢之后,Docker隨即創建engine對象,代碼如下:
eng := engine.New()
Engine是Docker架構中的運行引擎,同時也是Docker運行的核心模塊。Engine扮演著Docker Container存儲倉庫的角色,并且通過Job的形式管理Docker運行中涉及的所有任務。
Engine結構體的定義位于./docker/docker/engine/engine.go#L47-L60,具體代碼如下:
type Engine struct { handlers map[string]Handler catchall Handler hack Hack // data for temporary hackery (see hack.go) id string Stdout io.Writer Stderr io.Writer Stdin io.Reader Logging bool tasks sync.WaitGroup l sync.RWMutex // lock for shutdown shutdown bool onShutdown []func() // shutdown handlers }
Engine結構體中最為重要的是handlers屬性,handlers屬性為map類型,key的類型是string,value的類型是Handler。其中Handler類型的定義位于./docker/docker/engine/engine.go#L23,具體代碼如下:
type Handler func(*Job) Status
可見,Handler為一個定義的函數。該函數傳入的參數為Job指針,返回為Status狀態。
了解完Engine以及Handler的基本知識之后,我們真正進入創建Engine實例的部分,即New()函數的實現,具體代碼如下:
func New() *Engine { eng := &Engine{ handlers: make(map[string]Handler), id: utils.RandomString(), Stdout: os.Stdout, Stderr: os.Stderr, Stdin: os.Stdin, Logging: true, } eng.Register("commands", func(job *Job) Status { for _, name := range eng.commands() { job.Printf("%s\n", name) } return StatusOK }) // Copy existing global handlers for k, v := range globalHandlers { eng.handlers[k] = v } return eng }
分析以上代碼,從返回結果可以發現,New()函數最終返回一個Engine實例對象。而在代碼實現部分,大致可以將其分為三個步驟:
1)創建一個Engine結構體實例eng,并初始化部分屬性,如handlers、id、標準輸出stdout、日志屬性Logging等。
2)向eng對象注冊名為commands的Handler,其中Handler為臨時定義的函數func(job*Job)Status{},該函數的作用是通過Job來打印所有已經注冊完畢的command名稱,最終返回狀態StatusOK。
3)將變量globalHandlers中定義完畢的所有Handler都復制到eng對象的handlers屬性中。
至此,一個基本的Engine對象實例eng已經創建完畢,并實現部分屬性的初始化。Docker Daemon啟動的后續過程中,仍然會對Engine對象實例進行額外的配置。