func (d *DockerDiscovery) Run(looper director.Looper) {
	connQuitChan := make(chan bool)
	go d.manageConnection(connQuitChan)
	go func() {
		looper.Loop(func() error {
			select {
			case event := <-d.events:
				if event == nil {
					return nil
				}
				log.Debugf("Event: %#v\n", event)
				d.handleEvent(*event)
			case <-time.After(d.sleepInterval):
				d.getContainers()
			case <-time.After(CacheDrainInterval):
				d.containerCache.Drain(len(d.services))
			}
			return nil
		})
		close(connQuitChan)
	}()
}
The main loop, poll for containers continuously.
package discovery
import (
	"fmt"
	"strconv"
	"sync"
	"time"
	director "github.com/relistan/go-director"
	log "github.com/sirupsen/logrus"
	"github.com/NinesStack/sidecar/service"
	"github.com/fsouza/go-dockerclient"
)
const (
	CacheDrainInterval = 10 * time.Minute  
)
type DockerClient interface {
	InspectContainer(id string) (*docker.Container, error)
	ListContainers(opts docker.ListContainersOptions) ([]docker.APIContainers, error)
	AddEventListener(listener chan<- *docker.APIEvents) error
	RemoveEventListener(listener chan *docker.APIEvents) error
	Ping() error
}
type DockerDiscovery struct {
	events         chan *docker.APIEvents        
	endpoint       string                        
	services       []*service.Service            
	ClientProvider func() (DockerClient, error)  
	serviceNamer   ServiceNamer                  
	advertiseIp    string                        
	containerCache *ContainerCache               
	sleepInterval  time.Duration                 
	sync.RWMutex                                 
}
func NewDockerDiscovery(endpoint string, svcNamer ServiceNamer, ip string) *DockerDiscovery {
	discovery := DockerDiscovery{
		endpoint:       endpoint,
		events:         make(chan *docker.APIEvents),
		containerCache: NewContainerCache(),
		serviceNamer:   svcNamer,
		advertiseIp:    ip,
		sleepInterval:  DefaultSleepInterval,
	}
	discovery.ClientProvider = discovery.getDockerClient
	return &discovery
}
func (d *DockerDiscovery) getDockerClient() (DockerClient, error) {
	if d.endpoint != "" {
		client, err := docker.NewClient(d.endpoint)
		if err != nil {
			return nil, err
		}
		return client, nil
	}
	client, err := docker.NewClientFromEnv()
	if err != nil {
		return nil, err
	}
	return client, nil
}
func (d *DockerDiscovery) HealthCheck(svc *service.Service) (string, string) {
	container, err := d.inspectContainer(svc)
	if err != nil {
		return "", ""
	}
	return container.Config.Labels["HealthCheck"], container.Config.Labels["HealthCheckArgs"]
}
func (d *DockerDiscovery) inspectContainer(svc *service.Service) (*docker.Container, error) {
	container := d.containerCache.Get(svc.ID)
	if container != nil {
		return container, nil
	}
	client, err := d.ClientProvider()
	if err != nil {
		log.Errorf("Error when creating Docker client: %s\n", err.Error())
		return nil, err
	}
	container, err = client.InspectContainer(svc.ID)
	if err != nil {
		log.Errorf("Error inspecting container : %v\n", svc.ID)
		return nil, err
	}
	d.containerCache.Set(svc, container)
	return container, nil
}