1package zipkintracer
2
3import (
4	"strings"
5
6	"github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
7)
8
9// Collector represents a Zipkin trace collector, which is probably a set of
10// remote endpoints.
11type Collector interface {
12	Collect(*zipkincore.Span) error
13	Close() error
14}
15
16// NopCollector implements Collector but performs no work.
17type NopCollector struct{}
18
19// Collect implements Collector.
20func (NopCollector) Collect(*zipkincore.Span) error { return nil }
21
22// Close implements Collector.
23func (NopCollector) Close() error { return nil }
24
25// MultiCollector implements Collector by sending spans to all collectors.
26type MultiCollector []Collector
27
28// Collect implements Collector.
29func (c MultiCollector) Collect(s *zipkincore.Span) error {
30	return c.aggregateErrors(func(coll Collector) error { return coll.Collect(s) })
31}
32
33// Close implements Collector.
34func (c MultiCollector) Close() error {
35	return c.aggregateErrors(func(coll Collector) error { return coll.Close() })
36}
37
38func (c MultiCollector) aggregateErrors(f func(c Collector) error) error {
39	var e *collectionError
40	for i, collector := range c {
41		if err := f(collector); err != nil {
42			if e == nil {
43				e = &collectionError{
44					errs: make([]error, len(c)),
45				}
46			}
47			e.errs[i] = err
48		}
49	}
50	return e
51}
52
53// CollectionError represents an array of errors returned by one or more
54// failed Collector methods.
55type CollectionError interface {
56	Error() string
57	GetErrors() []error
58}
59
60type collectionError struct {
61	errs []error
62}
63
64func (c *collectionError) Error() string {
65	errs := []string{}
66	for _, err := range c.errs {
67		if err != nil {
68			errs = append(errs, err.Error())
69		}
70	}
71	return strings.Join(errs, "; ")
72}
73
74// GetErrors implements CollectionError
75func (c *collectionError) GetErrors() []error {
76	return c.errs
77}
78