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 .Optional ;
@@ -38,6 +40,9 @@ public class ReflectorRunnable<
38
40
private static final Logger log = LoggerFactory .getLogger (ReflectorRunnable .class );
39
41
40
42
private String lastSyncResourceVersion ;
43
+
44
+ private boolean isLastSyncResourceVersionUnavailable ;
45
+
41
46
private Watchable <ApiType > watch ;
42
47
43
48
private ListerWatcher <ApiType , ApiListType > listerWatcher ;
@@ -87,6 +92,7 @@ public void run() {
87
92
}
88
93
this .syncWith (items , resourceVersion );
89
94
this .lastSyncResourceVersion = resourceVersion ;
95
+ this .isLastSyncResourceVersionUnavailable = false ;
90
96
91
97
if (log .isDebugEnabled ()) {
92
98
log .debug ("{}#Start watching with {}..." , apiTypeClass , lastSyncResourceVersion );
@@ -146,6 +152,13 @@ public void run() {
146
152
closeWatch ();
147
153
}
148
154
}
155
+ } catch (ApiException e ) {
156
+ if (e .getCode () == HttpURLConnection .HTTP_GONE ) {
157
+ log .info (
158
+ "ResourceVersion {} expired, will retry w/o resourceVersion at the next time" ,
159
+ getRelistResourceVersion ());
160
+ isLastSyncResourceVersionUnavailable = true ;
161
+ }
149
162
} catch (Throwable t ) {
150
163
this .exceptionHandler .accept (apiTypeClass , t );
151
164
}
@@ -176,8 +189,23 @@ public String getLastSyncResourceVersion() {
176
189
return lastSyncResourceVersion ;
177
190
}
178
191
192
+ public boolean isLastSyncResourceVersionUnavailable () {
193
+ return isLastSyncResourceVersionUnavailable ;
194
+ }
195
+
179
196
private String getRelistResourceVersion () {
197
+ if (isLastSyncResourceVersionUnavailable ) {
198
+ // Since this reflector makes paginated list requests, and all paginated list requests skip
199
+ // the watch cache
200
+ // if the lastSyncResourceVersion is unavailable, we set ResourceVersion="" and list again to
201
+ // re-establish reflector
202
+ // to the latest available ResourceVersion, using a consistent read from etcd.
203
+ return "" ;
204
+ }
180
205
if (Strings .isNullOrEmpty (lastSyncResourceVersion )) {
206
+ // For performance reasons, initial list performed by reflector uses "0" as resource version
207
+ // to allow it to
208
+ // be served from the watch cache if it is enabled.
181
209
return "0" ;
182
210
}
183
211
return lastSyncResourceVersion ;
0 commit comments