github.com/lusis/distribution@v2.0.1+incompatible/notifications/endpoint.go (about)

     1  package notifications
     2  
     3  import (
     4  	"net/http"
     5  	"time"
     6  )
     7  
     8  // EndpointConfig covers the optional configuration parameters for an active
     9  // endpoint.
    10  type EndpointConfig struct {
    11  	Headers   http.Header
    12  	Timeout   time.Duration
    13  	Threshold int
    14  	Backoff   time.Duration
    15  }
    16  
    17  // defaults set any zero-valued fields to a reasonable default.
    18  func (ec *EndpointConfig) defaults() {
    19  	if ec.Timeout <= 0 {
    20  		ec.Timeout = time.Second
    21  	}
    22  
    23  	if ec.Threshold <= 0 {
    24  		ec.Threshold = 10
    25  	}
    26  
    27  	if ec.Backoff <= 0 {
    28  		ec.Backoff = time.Second
    29  	}
    30  }
    31  
    32  // Endpoint is a reliable, queued, thread-safe sink that notify external http
    33  // services when events are written. Writes are non-blocking and always
    34  // succeed for callers but events may be queued internally.
    35  type Endpoint struct {
    36  	Sink
    37  	url  string
    38  	name string
    39  
    40  	EndpointConfig
    41  
    42  	metrics *safeMetrics
    43  }
    44  
    45  // NewEndpoint returns a running endpoint, ready to receive events.
    46  func NewEndpoint(name, url string, config EndpointConfig) *Endpoint {
    47  	var endpoint Endpoint
    48  	endpoint.name = name
    49  	endpoint.url = url
    50  	endpoint.EndpointConfig = config
    51  	endpoint.defaults()
    52  	endpoint.metrics = newSafeMetrics()
    53  
    54  	// Configures the inmemory queue, retry, http pipeline.
    55  	endpoint.Sink = newHTTPSink(
    56  		endpoint.url, endpoint.Timeout, endpoint.Headers,
    57  		endpoint.metrics.httpStatusListener())
    58  	endpoint.Sink = newRetryingSink(endpoint.Sink, endpoint.Threshold, endpoint.Backoff)
    59  	endpoint.Sink = newEventQueue(endpoint.Sink, endpoint.metrics.eventQueueListener())
    60  
    61  	register(&endpoint)
    62  	return &endpoint
    63  }
    64  
    65  // Name returns the name of the endpoint, generally used for debugging.
    66  func (e *Endpoint) Name() string {
    67  	return e.name
    68  }
    69  
    70  // URL returns the url of the endpoint.
    71  func (e *Endpoint) URL() string {
    72  	return e.url
    73  }
    74  
    75  // ReadMetrics populates em with metrics from the endpoint.
    76  func (e *Endpoint) ReadMetrics(em *EndpointMetrics) {
    77  	e.metrics.Lock()
    78  	defer e.metrics.Unlock()
    79  
    80  	*em = e.metrics.EndpointMetrics
    81  	// Map still need to copied in a threadsafe manner.
    82  	em.Statuses = make(map[string]int)
    83  	for k, v := range e.metrics.Statuses {
    84  		em.Statuses[k] = v
    85  	}
    86  }