Skip to content

Commit b9e80fb

Browse files
committed
enforcing read-timeout for informer-factory processor via property "kubernetes.informer.clientReadTimeout"
1 parent bef3b24 commit b9e80fb

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerFactoryProcessor.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@
1717
import io.kubernetes.client.informer.SharedInformer;
1818
import io.kubernetes.client.informer.SharedInformerFactory;
1919
import io.kubernetes.client.informer.cache.Lister;
20+
import io.kubernetes.client.informer.cache.ReflectorRunnable;
2021
import io.kubernetes.client.openapi.ApiClient;
2122
import io.kubernetes.client.spring.extended.controller.annotation.KubernetesInformer;
2223
import io.kubernetes.client.spring.extended.controller.annotation.KubernetesInformers;
24+
import io.kubernetes.client.spring.extended.controller.config.KubernetesInformerProperties;
25+
import io.kubernetes.client.spring.extended.controller.factory.KubernetesControllerFactory;
2326
import io.kubernetes.client.util.generic.GenericKubernetesApi;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
2429
import org.springframework.beans.BeansException;
2530
import org.springframework.beans.factory.BeanFactory;
31+
import org.springframework.beans.factory.annotation.Autowired;
2632
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2733
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2834
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -45,6 +51,10 @@ public class KubernetesInformerFactoryProcessor
4551

4652
public static final int ORDER = 0;
4753

54+
private static final Logger log = LoggerFactory.getLogger(KubernetesControllerFactory.class);
55+
56+
@Autowired private KubernetesInformerProperties informerProperties;
57+
4858
private ConfigurableListableBeanFactory beanFactory;
4959

5060
@Override
@@ -122,6 +132,20 @@ private <T extends KubernetesObject> Lister<T> lister(Class<T> type) {
122132
private <T extends KubernetesObject> SharedInformer<T> informer(
123133
Class<T> type, KubernetesInformer kubernetesInformer) {
124134
ApiClient apiClient = this.beanFactory.getBean(ApiClient.class);
135+
136+
if (apiClient.getHttpClient().readTimeoutMillis() > 0) {
137+
log.warn(
138+
"Enforcing read-timeout of the ApiClient {} to {} so that the watch connection won't abort from client-side",
139+
apiClient,
140+
ReflectorRunnable.REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT);
141+
apiClient.setHttpClient(
142+
apiClient
143+
.getHttpClient()
144+
.newBuilder()
145+
.readTimeout(informerProperties.getClientReadTimeout())
146+
.build());
147+
}
148+
125149
SharedInformerFactory sharedInformerFactory =
126150
this.beanFactory.getBean(SharedInformerFactory.class);
127151
final GenericKubernetesApi api =

spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerAutoConfiguration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@
1818
import io.kubernetes.client.util.ClientBuilder;
1919
import java.io.IOException;
2020
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
21+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2122
import org.springframework.context.annotation.Bean;
2223
import org.springframework.context.annotation.Configuration;
2324

2425
@Configuration(proxyBeanMethods = false)
2526
@ConditionalOnKubernetesInformerEnabled
27+
@EnableConfigurationProperties({
28+
KubernetesInformerProperties.class,
29+
})
2630
public class KubernetesInformerAutoConfiguration {
2731

2832
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.spring.extended.controller.config;
14+
15+
import io.kubernetes.client.informer.cache.ReflectorRunnable;
16+
import java.time.Duration;
17+
import org.springframework.boot.context.properties.ConfigurationProperties;
18+
19+
@ConfigurationProperties("kubernetes.informer")
20+
public class KubernetesInformerProperties {
21+
22+
private Duration clientReadTimeout = ReflectorRunnable.REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT;
23+
24+
public Duration getClientReadTimeout() {
25+
return clientReadTimeout;
26+
}
27+
28+
public KubernetesInformerProperties setClientReadTimeout(Duration clientReadTimeout) {
29+
this.clientReadTimeout = clientReadTimeout;
30+
return this;
31+
}
32+
}

util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public class ReflectorRunnable<
3737
ApiType extends KubernetesObject, ApiListType extends KubernetesListObject>
3838
implements Runnable {
3939

40+
public static Duration REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT = Duration.ofMinutes(5);
41+
4042
private static final Logger log = LoggerFactory.getLogger(ReflectorRunnable.class);
4143

4244
private String lastSyncResourceVersion;
@@ -113,7 +115,7 @@ public void run() {
113115
new CallGeneratorParams(
114116
Boolean.TRUE,
115117
lastSyncResourceVersion,
116-
Long.valueOf(Duration.ofMinutes(5).getSeconds()).intValue()));
118+
Long.valueOf(REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT.getSeconds()).intValue()));
117119

118120
synchronized (this) {
119121
if (!isActive.get()) {

0 commit comments

Comments
 (0)