@@ -19,6 +19,7 @@ package controllers
1919import (
2020 "fmt"
2121 "sync"
22+ "time"
2223
2324 "k8s.io/api/discovery/v1beta1"
2425 discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
@@ -66,19 +67,83 @@ func (r *EndpointSliceReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro
6667 return ctrl.Result {}, nil
6768 }
6869
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+ }
7076
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+ }
74100 }
75101
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+ }
80143
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 })
82147}
83148
84149// SetServiceReconciler sets the service reconciler, so that the endpointslice
0 commit comments