func MonitorEndpoints(e Endpoints, options ...monitor.Option) (monitor.Interface, error) {
	if l, ok := e.(monitor.Listener); ok {
		options = append(options, monitor.WithListeners(l))
		return monitor.New(options...)
	}
	return nil, nil
}
MonitorEndpoints applies service discovery updates to the given Endpoints, if and only if the
Endpoints implements monitor.Listener.  If Endpoints does not implement monitor.Listener, this
function return a nil monitor and a nil error.
package fanout
import (
	"net/http"
	"net/url"
	"sync"
	"github.com/xmidt-org/webpa-common/v2/device"
	"github.com/xmidt-org/webpa-common/v2/service"
	"github.com/xmidt-org/webpa-common/v2/service/monitor"
	"github.com/xmidt-org/webpa-common/v2/service/servicehttp"
	"github.com/xmidt-org/webpa-common/v2/xhttp"
)
type ServiceEndpoints struct {
	lock            sync.RWMutex
	keyFunc         servicehttp.KeyFunc
	accessorFactory service.AccessorFactory
	accessors       map[string]service.Accessor
}
func (se *ServiceEndpoints) FanoutURLs(original *http.Request) ([]*url.URL, error) {
	hashKey, err := se.keyFunc(original)
	if err != nil {
		return nil, err
	}
	se.lock.RLock()
	endpoints := make([]string, 0, len(se.accessors))
	for _, a := range se.accessors {
		e, err := a.Get(hashKey)
		if err != nil {
			continue
		}
		endpoints = append(endpoints, e)
	}
	se.lock.RUnlock()
	if len(endpoints) == 0 {
		return []*url.URL{}, errNoFanoutURLs
	}
	return xhttp.ApplyURLParser(url.Parse, endpoints...)
}
func (se *ServiceEndpoints) MonitorEvent(e monitor.Event) {
	accessor := se.accessorFactory(e.Instances)
	se.lock.Lock()
	se.accessors[e.Key] = accessor
	se.lock.Unlock()
}
type ServiceEndpointsOption func(*ServiceEndpoints)
func WithKeyFunc(kf servicehttp.KeyFunc) ServiceEndpointsOption {
	return func(se *ServiceEndpoints) {
		if kf != nil {
			se.keyFunc = kf
		} else {
			se.keyFunc = device.IDHashParser
		}
	}
}
func WithAccessorFactory(af service.AccessorFactory) ServiceEndpointsOption {
	return func(se *ServiceEndpoints) {
		if af != nil {
			se.accessorFactory = af
		} else {
			se.accessorFactory = service.DefaultAccessorFactory
		}
	}
}
func NewServiceEndpoints(options ...ServiceEndpointsOption) *ServiceEndpoints {
	se := &ServiceEndpoints{
		keyFunc:         device.IDHashParser,
		accessorFactory: service.DefaultAccessorFactory,
		accessors:       make(map[string]service.Accessor),
	}
	for _, o := range options {
		o(se)
	}
	return se
}
func ServiceEndpointsAlternate(options ...ServiceEndpointsOption) func() (Endpoints, error) {
	return func() (Endpoints, error) {
		return NewServiceEndpoints(options...), nil
	}
}