27
27
28
28
import org .apache .http .ConnectionReuseStrategy ;
29
29
import org .apache .http .Header ;
30
- import org .apache .http .HeaderElement ;
31
- import org .apache .http .HeaderElementIterator ;
32
30
import org .apache .http .HttpHeaders ;
33
31
import org .apache .http .HttpHost ;
34
32
import org .apache .http .HttpResponse ;
33
+ import org .apache .http .NoHttpResponseException ;
35
34
import org .apache .http .auth .AuthScope ;
36
35
import org .apache .http .auth .UsernamePasswordCredentials ;
37
36
import org .apache .http .client .AuthCache ;
38
37
import org .apache .http .client .CredentialsProvider ;
38
+ import org .apache .http .client .HttpRequestRetryHandler ;
39
39
import org .apache .http .client .config .RequestConfig ;
40
40
import org .apache .http .client .protocol .HttpClientContext ;
41
41
import org .apache .http .config .ConnectionConfig ;
42
42
import org .apache .http .config .RegistryBuilder ;
43
- import org .apache .http .conn .ConnectionKeepAliveStrategy ;
44
43
import org .apache .http .conn .socket .ConnectionSocketFactory ;
45
44
import org .apache .http .conn .socket .PlainConnectionSocketFactory ;
46
45
import org .apache .http .conn .ssl .NoopHostnameVerifier ;
50
49
import org .apache .http .impl .client .BasicAuthCache ;
51
50
import org .apache .http .impl .client .BasicCredentialsProvider ;
52
51
import org .apache .http .impl .client .CloseableHttpClient ;
52
+ import org .apache .http .impl .client .DefaultHttpRequestRetryHandler ;
53
53
import org .apache .http .impl .client .HttpClientBuilder ;
54
54
import org .apache .http .impl .conn .PoolingHttpClientConnectionManager ;
55
55
import org .apache .http .message .BasicHeader ;
56
- import org .apache .http .message .BasicHeaderElementIterator ;
57
- import org .apache .http .protocol .HTTP ;
58
56
import org .apache .http .protocol .HttpContext ;
59
57
60
58
import ru .yandex .clickhouse .settings .ClickHouseProperties ;
@@ -71,16 +69,32 @@ public ClickHouseHttpClientBuilder(ClickHouseProperties properties) {
71
69
public CloseableHttpClient buildClient () throws Exception {
72
70
return HttpClientBuilder .create ()
73
71
.setConnectionManager (getConnectionManager ())
72
+ .setRetryHandler (getRequestRetryHandler ())
74
73
.setConnectionReuseStrategy (getConnectionReuseStrategy ())
75
74
.setDefaultConnectionConfig (getConnectionConfig ())
76
75
.setDefaultRequestConfig (getRequestConfig ())
77
76
.setDefaultHeaders (getDefaultHeaders ())
78
77
.setDefaultCredentialsProvider (getDefaultCredentialsProvider ())
79
- .disableContentCompression () // gzip здесь ни к чему. Используется lz4 при compress=1
78
+ .disableContentCompression () // gzip is not needed. Use lz4 when compress=1
80
79
.disableRedirectHandling ()
81
80
.build ();
82
81
}
83
82
83
+ private HttpRequestRetryHandler getRequestRetryHandler () {
84
+ final int maxRetries = properties .getMaxRetries ();
85
+ return new DefaultHttpRequestRetryHandler (maxRetries , false ) {
86
+ @ Override
87
+ public boolean retryRequest (IOException exception , int executionCount , HttpContext context ) {
88
+ if (executionCount > maxRetries || context == null
89
+ || !Boolean .TRUE .equals (context .getAttribute ("is_idempotent" ))) {
90
+ return false ;
91
+ }
92
+
93
+ return (exception instanceof NoHttpResponseException ) || super .retryRequest (exception , executionCount , context );
94
+ }
95
+ };
96
+ }
97
+
84
98
public static HttpClientContext createClientContext (ClickHouseProperties props ) {
85
99
if (props == null
86
100
|| !isConfigurationValidForAuth (props ))
@@ -155,29 +169,6 @@ private Collection<Header> getDefaultHeaders() {
155
169
return headers ;
156
170
}
157
171
158
- private ConnectionKeepAliveStrategy createKeepAliveStrategy () {
159
- return new ConnectionKeepAliveStrategy () {
160
- @ Override
161
- public long getKeepAliveDuration (HttpResponse httpResponse , HttpContext httpContext ) {
162
- // in case of errors keep-alive not always works. close connection just in case
163
- if (httpResponse .getStatusLine ().getStatusCode () != HttpURLConnection .HTTP_OK ) {
164
- return -1 ;
165
- }
166
- HeaderElementIterator it = new BasicHeaderElementIterator (
167
- httpResponse .headerIterator (HTTP .CONN_DIRECTIVE ));
168
- while (it .hasNext ()) {
169
- HeaderElement he = it .nextElement ();
170
- String param = he .getName ();
171
- //String value = he.getValue();
172
- if (param != null && param .equalsIgnoreCase (HTTP .CONN_KEEP_ALIVE )) {
173
- return properties .getKeepAliveTimeout ();
174
- }
175
- }
176
- return -1 ;
177
- }
178
- };
179
- }
180
-
181
172
private SSLContext getSSLContext ()
182
173
throws CertificateException , NoSuchAlgorithmException , KeyStoreException , IOException , KeyManagementException {
183
174
SSLContext ctx = SSLContext .getInstance ("TLS" );
0 commit comments