Docker Swarm程式碼分析筆記(17)——event_monitor.go

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Engine結構體有一個eventsMonitor成員:

type Engine struct {    ......    eventsMonitor   *EventsMonitor}

EventsMonitor結構體定義如下:

//EventsMonitor monitors eventstype EventsMonitor struct {    stopChan chan struct{}    cli      client.APIClient    handler  func(msg events.Message) error}

stopChan用來通知停止接受訊息;cli是底層串連的client,而handler則是收到event的處理函數。

Engine.ConnectWithClient方法會給eventsMonitor成員賦值:

// ConnectWithClient is exportedfunc (e *Engine) ConnectWithClient(client dockerclient.Client, apiClient engineapi.APIClient) error {    e.client = client    e.apiClient = apiClient    e.eventsMonitor = NewEventsMonitor(e.apiClient, e.handler)    // Fetch the engine labels.    if err := e.updateSpecs(); err != nil {        return err    }    e.StartMonitorEvents()    // Force a state update before returning.    if err := e.RefreshContainers(true); err != nil {        return err    }    if err := e.RefreshImages(); err != nil {        return err    }    // Do not check error as older daemon does't support this call.    e.RefreshVolumes()    e.RefreshNetworks()    e.emitEvent("engine_connect")    return nil}

其中Engine.StartMonitorEvents代碼如下:

// StartMonitorEvents monitors events from the enginefunc (e *Engine) StartMonitorEvents() {    log.WithFields(log.Fields{"name": e.Name, "id": e.ID}).Debug("Start monitoring events")    ec := make(chan error)    e.eventsMonitor.Start(ec)    go func() {        if err := <-ec; err != nil {            if !strings.Contains(err.Error(), "EOF") {                // failing node reconnect should use back-off strategy                <-e.refreshDelayer.Wait(e.getFailureCount())            }            e.StartMonitorEvents()        }        close(ec)    }()}

Engine.StartMonitorEvents就是如果從ec channel收取訊息,如果是錯誤,就不斷地迴圈啟動Engine.StartMonitorEvents

EventsMonitor.Start函數代碼如下:

// Start starts the EventsMonitorfunc (em *EventsMonitor) Start(ec chan error) {    em.stopChan = make(chan struct{})    responseBody, err := em.cli.Events(context.Background(), types.EventsOptions{})    if err != nil {        ec <- err        return    }    resultChan := make(chan decodingResult)    go func() {        dec := json.NewDecoder(responseBody)        for {            var result decodingResult            result.err = dec.Decode(&result.msg)            resultChan <- result            if result.err == io.EOF {                break            }        }        close(resultChan)    }()    go func() {        defer responseBody.Close()        for {            select {            case <-em.stopChan:                ec <- nil                return            case result := <-resultChan:                if result.err != nil {                    ec <- result.err                    return                }                if err := em.handler(result.msg); err != nil {                    ec <- err                    return                }            }        }    }()}

代碼邏輯實際就是發出“HTTP GET /events”請求,然後等待Docker Engine的響應。因為這個HTTP請求很可能會阻塞在這裡,因此隨後的HTTP訊息互動就會重建立立一個HTTP串連。原理在這裡:

type Response struct {    ......    // Body represents the response body.    //    // The http Client and Transport guarantee that Body is always    // non-nil, even on responses without a body or responses with    // a zero-length body. It is the caller's responsibility to    // close Body. The default HTTP client's Transport does not    // attempt to reuse HTTP/1.0 or HTTP/1.1 TCP connections    // ("keep-alive") unless the Body is read to completion and is    // closed.    //    // The Body is automatically dechunked if the server replied    // with a "chunked" Transfer-Encoding.    Body io.ReadCloser    ......}

如果想停止這個EventsMonitor,可以使用Engine.Stop方法:

// Stop stops the EventsMonitorfunc (em *EventsMonitor) Stop() {    if em.stopChan == nil {        return    }    close(em.stopChan)}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.