...
1
16
17 package metrics
18
19 import (
20 "math"
21 "sync"
22
23 "k8s.io/apimachinery/pkg/types"
24 endpointsliceutil "k8s.io/endpointslice/util"
25 )
26
27
28 func NewCache(endpointsPerSlice int32) *Cache {
29 return &Cache{
30 maxEndpointsPerSlice: endpointsPerSlice,
31 cache: map[types.NamespacedName]*EndpointPortCache{},
32 }
33 }
34
35
36
37 type Cache struct {
38
39
40 maxEndpointsPerSlice int32
41
42
43 lock sync.Mutex
44
45
46 numEndpoints int
47
48
49 cache map[types.NamespacedName]*EndpointPortCache
50 }
51
52
53
54
55 type EndpointPortCache struct {
56 items map[endpointsliceutil.PortMapKey]EfficiencyInfo
57 }
58
59
60
61
62 type EfficiencyInfo struct {
63 Endpoints int
64 Slices int
65 }
66
67
68 func NewEndpointPortCache() *EndpointPortCache {
69 return &EndpointPortCache{
70 items: map[endpointsliceutil.PortMapKey]EfficiencyInfo{},
71 }
72 }
73
74
75
76 func (spc *EndpointPortCache) Set(pmKey endpointsliceutil.PortMapKey, eInfo EfficiencyInfo) {
77 spc.items[pmKey] = eInfo
78 }
79
80
81
82 func (spc *EndpointPortCache) numEndpoints() int {
83 num := 0
84 for _, eInfo := range spc.items {
85 num += eInfo.Endpoints
86 }
87 return num
88 }
89
90
91
92
93
94
95 func (c *Cache) UpdateEndpointPortCache(endpointsNN types.NamespacedName, epCache *EndpointPortCache) {
96 c.lock.Lock()
97 defer c.lock.Unlock()
98
99 prevNumEndpoints := 0
100 if existingEPCache, ok := c.cache[endpointsNN]; ok {
101 prevNumEndpoints = existingEPCache.numEndpoints()
102 }
103
104 currNumEndpoints := epCache.numEndpoints()
105
106
107 c.numEndpoints = c.numEndpoints + currNumEndpoints - prevNumEndpoints
108
109 c.cache[endpointsNN] = epCache
110 c.updateMetrics()
111 }
112
113
114
115 func (c *Cache) DeleteEndpoints(endpointsNN types.NamespacedName) {
116 c.lock.Lock()
117 defer c.lock.Unlock()
118
119 if spCache, ok := c.cache[endpointsNN]; ok {
120 c.numEndpoints = c.numEndpoints - spCache.numEndpoints()
121 delete(c.cache, endpointsNN)
122 c.updateMetrics()
123 }
124 }
125
126
127 type metricsUpdate struct {
128 desired, actual int
129 }
130
131
132
133
134 func (c *Cache) desiredAndActualSlices() metricsUpdate {
135 mUpdate := metricsUpdate{}
136 for _, spCache := range c.cache {
137 for _, eInfo := range spCache.items {
138 mUpdate.actual += eInfo.Slices
139 mUpdate.desired += numDesiredSlices(eInfo.Endpoints, int(c.maxEndpointsPerSlice))
140 }
141 }
142 return mUpdate
143 }
144
145
146
147 func (c *Cache) updateMetrics() {
148 mUpdate := c.desiredAndActualSlices()
149 NumEndpointSlices.WithLabelValues().Set(float64(mUpdate.actual))
150 DesiredEndpointSlices.WithLabelValues().Set(float64(mUpdate.desired))
151 EndpointsDesired.WithLabelValues().Set(float64(c.numEndpoints))
152 }
153
154
155
156 func numDesiredSlices(numEndpoints, maxPerSlice int) int {
157 return int(math.Ceil(float64(numEndpoints) / float64(maxPerSlice)))
158 }
159
View as plain text