@@ -19,6 +19,7 @@ package controllers
19
19
import (
20
20
"fmt"
21
21
"sync"
22
+ "time"
22
23
23
24
"k8s.io/api/discovery/v1beta1"
24
25
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
@@ -66,19 +67,83 @@ func (r *EndpointSliceReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro
66
67
return ctrl.Result {}, nil
67
68
}
68
69
69
- r .epsliceCounter .putSrvCount (req .Namespace , data .srv , req .Name , data .count )
70
+ srvname := ktypes.NamespacedName {Namespace : req .Namespace , Name : data .srv }
71
+ wind , exists := r .srvWindows [srvname .String ()]
72
+ if ! exists {
73
+ r .srvWindows [srvname .String ()] = & window {values : []* windowValue {}}
74
+ wind = r .srvWindows [srvname .String ()]
75
+ }
70
76
71
- if r .srvRecon == nil {
72
- l .Error (fmt .Errorf ("service reconciler is nil" ), "could not reconcile service from endpointslice" )
73
- return ctrl.Result {}, nil
77
+ wind .lock .Lock ()
78
+ defer wind .lock .Unlock ()
79
+
80
+ countBeforeUpd := r .epsliceCounter .getSrvCount (srvname .Namespace , srvname .Name )
81
+ r .epsliceCounter .putSrvCount (req .Namespace , srvname .Name , req .Name , data .count )
82
+ newCount := r .epsliceCounter .getSrvCount (srvname .Namespace , srvname .Name )
83
+
84
+ if len (wind .values ) > 0 {
85
+ if newCount > wind .getHighest () {
86
+ l .Info ("new count detected and is the highest in the window, updating service registry..." , "highest" , wind .getHighest (), "new-count" , newCount )
87
+ r .srvRecon .cacheSrvWatch [srvname .String ()] = true
88
+ r .srvRecon .Reconcile (ctrl.Request {NamespacedName : srvname })
89
+ } else {
90
+ l .Info ("new count detected, but not highest in window: performing cooldown..." , "highest" , wind .getHighest (), "new-count" , newCount )
91
+ }
92
+ } else {
93
+ if newCount > countBeforeUpd {
94
+ l .Info ("new count detected and window is empty, updating service registry..." , "old-val" , countBeforeUpd , "new-val" , newCount )
95
+ r .srvRecon .cacheSrvWatch [srvname .String ()] = true
96
+ r .srvRecon .Reconcile (ctrl.Request {NamespacedName : srvname })
97
+ } else {
98
+ l .Info ("new count detected, but not higher than current value, performing cooldown..." , "old-val" , countBeforeUpd , "new-val" , newCount )
99
+ }
74
100
}
75
101
76
- srvname := ktypes.NamespacedName {Namespace : req .Namespace , Name : data .srv }
77
- r .srvRecon .lock .Lock ()
78
- r .srvRecon .cacheSrvWatch [srvname .String ()] = true
79
- r .srvRecon .lock .Unlock ()
102
+ wind .values = append (wind .values , & windowValue {
103
+ epsliceName : req .Name ,
104
+ epsliceCount : data .count ,
105
+ totalCount : newCount ,
106
+ timer : time .AfterFunc (time .Minute , func () {
107
+ r .exitWindow (srvname )
108
+ }),
109
+ })
110
+
111
+ return ctrl.Result {}, nil
112
+ }
113
+
114
+ func (r * EndpointSliceReconciler ) exitWindow (srv ktypes.NamespacedName ) {
115
+ l := r .Log .WithName ("EndpointSliceReconciler" ).WithValues ("Window" , srv )
116
+
117
+ wind := r .srvWindows [srv .String ()]
118
+ wind .lock .Lock ()
119
+ defer wind .lock .Unlock ()
120
+
121
+ if len (wind .values ) == 0 {
122
+ l .V (2 ).Info ("window is empty, returning..." )
123
+ return
124
+ }
125
+
126
+ oldestVal := wind .values [0 ]
127
+ oldestVal .timer .Stop ()
128
+ defer func () {
129
+ wind .values = wind .values [1 :]
130
+ }()
131
+
132
+ highestVal := r .epsliceCounter .getSrvCount (srv .Namespace , srv .Name )
133
+ for i := 1 ; i < len (wind .values ); i ++ {
134
+ if wind .values [i ].totalCount > highestVal {
135
+ highestVal = wind .values [i ].totalCount
136
+ }
137
+ }
138
+
139
+ if oldestVal .totalCount <= highestVal && len (wind .values ) > 1 {
140
+ l .Info ("highest value isn't changed, returning..." , "exiting-value" , oldestVal .totalCount , "highest" , highestVal )
141
+ return
142
+ }
80
143
81
- return r .srvRecon .Reconcile (ctrl.Request {NamespacedName : srvname })
144
+ l .Info ("updating service registry..." , "highest-value" , highestVal )
145
+ r .srvRecon .cacheSrvWatch [srv .String ()] = true
146
+ r .srvRecon .Reconcile (ctrl.Request {NamespacedName : srv })
82
147
}
83
148
84
149
// SetServiceReconciler sets the service reconciler, so that the endpointslice
0 commit comments