Repository: traefik/traefik
File: pkg/healthcheck/healthcheck.go (Go)

Code before:
		return err
	}
	if lb.serviceInfo != nil {
		lb.serviceInfo.UpdateServerStatus(u.String(), serverUp)
	}
	log.FromContext(ctx).Debugf("child %s now %s", u.String(), serverUp)

	if upBefore {
		// we were up, and we still are, no need to propagate
		log.FromContext(ctx).Debugf("Still %s, no need to propagate", serverUp)
		return nil
	}

	log.FromContext(ctx).Debugf("Propagating new %s status", serverUp)
	for _, fn := range lb.updaters {
		fn(true)
	}
	return nil
}

// Balancers is a list of Balancers(s) that implements the Balancer interface.
type Balancers []Balancer

// Servers returns the deduplicated server URLs from all the Balancer.
// As we are only supporting the RoundRobin balancer implementation from oxy we are using the same method to deduplicate
// the server URLs (see https://github.com/vulcand/oxy/blob/fb2728c857b7973a27f8de2f2190729c0f22cf49/roundrobin/rr.go#L347).
func (b Balancers) Servers() []*url.URL {
	uniqServers := make(map[string]struct{})

	var servers []*url.URL
	for _, lb := range b {
		for _, server := range lb.Servers() {
			key := serverKey(server)
			if _, ok := uniqServers[key]; ok {
				continue
			}

			servers = append(servers, server)
			uniqServers[key] = struct{}{}
		}
	}

	return servers
}

// RemoveServer removes the given server from all the Balancer,
// and updates the status of the server to "DOWN".
func (b Balancers) RemoveServer(u *url.URL) error {
	for _, lb := range b {
		if err := lb.RemoveServer(u); err != nil {
			return err

Review comment (suggestion):
```suggestion
// Note that the deduplication is only possible because all the underlying
// balancers are of the same kind (the oxy implementation). The comparison property
// is the same as the one found at:
// https://github.com/vulcand/oxy/blob/fb2728c857b7973a27f8de2f2190729c0f22cf49/roundrobin/rr.go#L347.
```

Code after:
		return err
	}
	if lb.serviceInfo != nil {
		lb.serviceInfo.UpdateServerStatus(u.String(), serverUp)
	}
	log.FromContext(ctx).Debugf("child %s now %s", u.String(), serverUp)

	if upBefore {
		// we were up, and we still are, no need to propagate
		log.FromContext(ctx).Debugf("Still %s, no need to propagate", serverUp)
		return nil
	}

	log.FromContext(ctx).Debugf("Propagating new %s status", serverUp)
	for _, fn := range lb.updaters {
		fn(true)
	}
	return nil
}

// Balancers is a list of Balancers(s) that implements the Balancer interface.
type Balancers []Balancer

// Servers returns the deduplicated server URLs from all the Balancer.
// Note that the deduplication is only possible because all the underlying
// balancers are of the same kind (the oxy implementation).
// The comparison property is the same as the one found at:
// https://github.com/vulcand/oxy/blob/fb2728c857b7973a27f8de2f2190729c0f22cf49/roundrobin/rr.go#L347.
func (b Balancers) Servers() []*url.URL {
	seen := make(map[string]struct{})

	var servers []*url.URL
	for _, lb := range b {
		for _, server := range lb.Servers() {
			key := serverKey(server)
			if _, ok := seen[key]; ok {
				continue
			}

			servers = append(servers, server)
			seen[key] = struct{}{}
		}
	}

	return servers
}

// RemoveServer removes the given server from all the Balancer,
// and updates the status of the server to "DOWN".
func (b Balancers) RemoveServer(u *url.URL) error {
	for _, lb := range b {