Skip to content

RemoveEventListener cause connection leak #911

@shabicheng

Description

@shabicheng

Recently both our app and docker engine found fd count increase in a short time, after looking into the go-dockerclient source code and test, we find the AddEventListener and RemoveEventListener cause the problem: RemoveEventListener will not close connection, but after remove all listener and call AddEventListener again, the client will create a new connection.

After looking into the code, we find that the eventHijack create the gorountine and will not return when we call RemoveEventListener :

https://github.com/fsouza/go-dockerclient/blob/main/event.go#L383

image

Now the newest go-dockerclient version has this problem.

The test:

image

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"time"

	docker "github.com/fsouza/go-dockerclient"
)

func main() {
	fmt.Println("Start running daemon")

	//Init Docker client
	endpoint := "unix:///var/run/docker.sock"

	if len(os.Args) < 3 {
		fmt.Printf(`Usage %s [unix-socket-path] [fd-path]
		example: %s unix:///var/run/docker.sock /proc/$(pidof docker)/fd`, os.Args[0], os.Args[0])
		os.Exit(2)
	}
	endpoint = os.Args[1]
	fdDir := os.Args[2]

	client, err := docker.NewClient(endpoint)

	if err != nil {
		log.Fatal(err)
	}

	for {
		connect(client, endpoint, fdDir)
	}
}

func connect(client *docker.Client, endpoint, fdDir string) {
	arr, err := ioutil.ReadDir(fdDir)
	if err != nil {
		log.Fatalf("read fd dir error %s: %v", fdDir, err)
	}
	fmt.Println(time.Now().Format("Mon Jan 02 15:04:05"), "before connect fd count:", len(arr))
	events := make(chan *docker.APIEvents)
	client.AddEventListener(events)

	defer func() {
		client.RemoveEventListener(events)

	}()
	timeout := time.After(3 * time.Second)
	select {
	case msg := <-events:
		if msg.Status == "start" {
			fmt.Println("EVENT:" + msg.Status)
		}
	case <-timeout:
		break
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions