1package config
2
3import (
4	"fmt"
5	"time"
6)
7
8const (
9	// DefaultDedupPrefix is the default prefix used for deduplication mode.
10	DefaultDedupPrefix = "consul-template/dedup/"
11
12	// DefaultDedupTTL is the default TTL for deduplicate mode.
13	DefaultDedupTTL = 15 * time.Second
14
15	// DefaultDedupMaxStale is the default max staleness for the deduplication
16	// manager.
17	DefaultDedupMaxStale = DefaultMaxStale
18)
19
20// DedupConfig is used to enable the de-duplication mode, which depends
21// on electing a leader per-template and watching of a key. This is used
22// to reduce the cost of many instances of CT running the same template.
23type DedupConfig struct {
24	// Controls if deduplication mode is enabled
25	Enabled *bool `mapstructure:"enabled"`
26
27	// MaxStale is the maximum amount of time to allow for stale queries.
28	MaxStale *time.Duration `mapstructure:"max_stale"`
29
30	// Controls the KV prefix used. Defaults to defaultDedupPrefix
31	Prefix *string `mapstructure:"prefix"`
32
33	// TTL is the Session TTL used for lock acquisition, defaults to 15 seconds.
34	TTL *time.Duration `mapstructure:"ttl"`
35}
36
37// DefaultDedupConfig returns a configuration that is populated with the
38// default values.
39func DefaultDedupConfig() *DedupConfig {
40	return &DedupConfig{}
41}
42
43// Copy returns a deep copy of this configuration.
44func (c *DedupConfig) Copy() *DedupConfig {
45	if c == nil {
46		return nil
47	}
48
49	var o DedupConfig
50	o.Enabled = c.Enabled
51	o.MaxStale = c.MaxStale
52	o.Prefix = c.Prefix
53	o.TTL = c.TTL
54	return &o
55}
56
57// Merge combines all values in this configuration with the values in the other
58// configuration, with values in the other configuration taking precedence.
59// Maps and slices are merged, most other values are overwritten. Complex
60// structs define their own merge functionality.
61func (c *DedupConfig) Merge(o *DedupConfig) *DedupConfig {
62	if c == nil {
63		if o == nil {
64			return nil
65		}
66		return o.Copy()
67	}
68
69	if o == nil {
70		return c.Copy()
71	}
72
73	r := c.Copy()
74
75	if o.Enabled != nil {
76		r.Enabled = o.Enabled
77	}
78
79	if o.MaxStale != nil {
80		r.MaxStale = o.MaxStale
81	}
82
83	if o.Prefix != nil {
84		r.Prefix = o.Prefix
85	}
86
87	if o.TTL != nil {
88		r.TTL = o.TTL
89	}
90
91	return r
92}
93
94// Finalize ensures there no nil pointers.
95func (c *DedupConfig) Finalize() {
96	if c.Enabled == nil {
97		c.Enabled = Bool(false ||
98			TimeDurationPresent(c.MaxStale) ||
99			StringPresent(c.Prefix) ||
100			TimeDurationPresent(c.TTL))
101	}
102
103	if c.MaxStale == nil {
104		c.MaxStale = TimeDuration(DefaultDedupMaxStale)
105	}
106
107	if c.Prefix == nil {
108		c.Prefix = String(DefaultDedupPrefix)
109	}
110
111	if c.TTL == nil {
112		c.TTL = TimeDuration(DefaultDedupTTL)
113	}
114}
115
116// GoString defines the printable version of this struct.
117func (c *DedupConfig) GoString() string {
118	if c == nil {
119		return "(*DedupConfig)(nil)"
120	}
121	return fmt.Sprintf("&DedupConfig{"+
122		"Enabled:%s, "+
123		"MaxStale:%s, "+
124		"Prefix:%s, "+
125		"TTL:%s"+
126		"}",
127		BoolGoString(c.Enabled),
128		TimeDurationGoString(c.MaxStale),
129		StringGoString(c.Prefix),
130		TimeDurationGoString(c.TTL),
131	)
132}
133