16
16
import io .kubernetes .client .common .KubernetesObject ;
17
17
import io .kubernetes .client .informer .EventType ;
18
18
import io .kubernetes .client .informer .ListerWatcher ;
19
+ import io .kubernetes .client .openapi .ApiException ;
19
20
import io .kubernetes .client .openapi .models .V1ListMeta ;
20
21
import io .kubernetes .client .openapi .models .V1ObjectMeta ;
21
22
import io .kubernetes .client .util .CallGeneratorParams ;
22
23
import io .kubernetes .client .util .Strings ;
23
24
import io .kubernetes .client .util .Watchable ;
24
25
import java .io .IOException ;
25
26
import java .net .ConnectException ;
27
+ import java .net .HttpURLConnection ;
26
28
import java .time .Duration ;
27
29
import java .util .List ;
28
30
import java .util .concurrent .atomic .AtomicBoolean ;
@@ -37,6 +39,9 @@ public class ReflectorRunnable<
37
39
private static final Logger log = LoggerFactory .getLogger (ReflectorRunnable .class );
38
40
39
41
private String lastSyncResourceVersion ;
42
+
43
+ private boolean isLastSyncResourceVersionUnavailable ;
44
+
40
45
private Watchable <ApiType > watch ;
41
46
42
47
private ListerWatcher <ApiType , ApiListType > listerWatcher ;
@@ -86,6 +91,7 @@ public void run() {
86
91
}
87
92
this .syncWith (items , resourceVersion );
88
93
this .lastSyncResourceVersion = resourceVersion ;
94
+ this .isLastSyncResourceVersionUnavailable = false ;
89
95
90
96
if (log .isDebugEnabled ()) {
91
97
log .debug ("{}#Start watching with {}..." , apiTypeClass , lastSyncResourceVersion );
@@ -145,6 +151,13 @@ public void run() {
145
151
closeWatch ();
146
152
}
147
153
}
154
+ } catch (ApiException e ) {
155
+ if (e .getCode () == HttpURLConnection .HTTP_GONE ) {
156
+ log .info (
157
+ "ResourceVersion {} expired, will retry w/o resourceVersion at the next time" ,
158
+ getRelistResourceVersion ());
159
+ isLastSyncResourceVersionUnavailable = true ;
160
+ }
148
161
} catch (Throwable t ) {
149
162
this .exceptionHandler .accept (apiTypeClass , t );
150
163
}
@@ -175,8 +188,23 @@ public String getLastSyncResourceVersion() {
175
188
return lastSyncResourceVersion ;
176
189
}
177
190
191
+ public boolean isLastSyncResourceVersionUnavailable () {
192
+ return isLastSyncResourceVersionUnavailable ;
193
+ }
194
+
178
195
private String getRelistResourceVersion () {
196
+ if (isLastSyncResourceVersionUnavailable ) {
197
+ // Since this reflector makes paginated list requests, and all paginated list requests skip
198
+ // the watch cache
199
+ // if the lastSyncResourceVersion is unavailable, we set ResourceVersion="" and list again to
200
+ // re-establish reflector
201
+ // to the latest available ResourceVersion, using a consistent read from etcd.
202
+ return "" ;
203
+ }
179
204
if (Strings .isNullOrEmpty (lastSyncResourceVersion )) {
205
+ // For performance reasons, initial list performed by reflector uses "0" as resource version
206
+ // to allow it to
207
+ // be served from the watch cache if it is enabled.
180
208
return "0" ;
181
209
}
182
210
return lastSyncResourceVersion ;
0 commit comments