Project

General

Profile

« Previous | Next » 

Revision e2766ed7

Added by Andreas Kohlbecker about 4 years ago

ref #8812 setting NoConnectionReuseStrategy for PoolingHttpClientConnectionManager to avoid NoHttpResponseExceptions

View differences:

eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java
113 113
     * cdm servers when the network quality is too bad.
114 114
     *
115 115
     */
116
    public static final int HTTP_READ_TIMEOUT_MIN = 1000; // one minute
116
    public static final int HTTP_READ_TIMEOUT_MIN = 1000; // one second
117 117

  
118 118
    /**
119 119
     * Timeout for normal operation (milliseconds)
......
124 124
     * <p>
125 125
     * The application should be usable in networks with low connection quality,
126 126
     * e.g.: from cuba where the throughput rate is low (<= ISDN speed, 64 kbit)
127
     * and a packet delay of <200 ms. Additionally we should tolerate a certain
128
     * amount of packet loss. Here we take the packet loss rate as it occurs
129
     * in the FU-Berlin ZEDAT VPN as reference case (~1%)
130
     * <ul>
131
     * <li>5min: Timeout at remoting/taxonnode.service
132
     * </ul>
127
     * and a packet delay of <200 ms.
133 128
     *
134 129
     */
135
    public static final int HTTP_READ_TIMEOUT = 70000;
130
    public static final int HTTP_READ_TIMEOUT = 10 * 60 * 1000;
136 131

  
137 132

  
138 133
    protected ApplicationContext applicationContext;
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/service/TimestampingHttpInvokerRequestExecutor.java
17 17
import org.apache.http.HttpResponse;
18 18
import org.apache.http.client.HttpClient;
19 19
import org.apache.http.client.methods.HttpPost;
20
import org.apache.http.config.Registry;
21
import org.apache.http.config.RegistryBuilder;
22
import org.apache.http.conn.socket.ConnectionSocketFactory;
23
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
24
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
25
import org.apache.http.impl.NoConnectionReuseStrategy;
26
import org.apache.http.impl.client.HttpClientBuilder;
27
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
20 28
import org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor;
21 29
import org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration;
22 30

  
23 31
import eu.etaxonomy.taxeditor.remoting.RemoteExecutionTimestampsUtil;
24 32

  
25 33
/**
34
 * HttpInvokerRequestExecutor which extends the {@link HttpComponentsHttpInvokerRequestExecutor} by two functionalities:
35
 *
36
 * <ol>
37
 * <li>Records time stamps when sending the request and when receiving the response.</li>
38
 * <li>Allows custom configuration of the {@link PoolingHttpClientConnectionManager}
39
 * (see <a href="https://dev.e-taxonomy.eu/redmine/issues/8812">https://dev.e-taxonomy.eu/redmine/issues/8812</a>).
40
 * </ol>
41
 *
26 42
 * @author a.kohlbecker
27 43
 * @since Jan 17, 2020
28 44
 */
29 45
public class TimestampingHttpInvokerRequestExecutor extends HttpComponentsHttpInvokerRequestExecutor {
30 46

  
47
    private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100;
48

  
49
    private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;
50

  
51
    /**
52
     * Default in PoolingHttpClientConnectionManager is 2000 milliseconds.
53
     *
54
     * see https://stackoverflow.com/questions/10558791/apache-httpclient-interim-error-nohttpresponseexception
55
     */
56
    private static final int VALIDATE_AFTER_INACTIVITY = 2000;
57

  
58
    public TimestampingHttpInvokerRequestExecutor() {
59
        super(createDefaultHttpClient());
60
    }
61

  
62

  
31 63
    @Override
32 64
    protected HttpResponse executeHttpPost(HttpInvokerClientConfiguration config, HttpClient httpClient,
33 65
            HttpPost httpPost) throws IOException {
......
60 92
        }
61 93
    }
62 94

  
95
    private static HttpClient createDefaultHttpClient() {
96
        Registry<ConnectionSocketFactory> schemeRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
97
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
98
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
99
                .build();
100

  
101
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(schemeRegistry);
102
        connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
103
        connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
104
        connectionManager.setValidateAfterInactivity(VALIDATE_AFTER_INACTIVITY);
105

  
106
        return HttpClientBuilder.create()
107
                .setConnectionManager(connectionManager)
108
                .setConnectionReuseStrategy(new NoConnectionReuseStrategy()) // see #8812
109
                .build();
110
    }
111

  
63 112
}
eu.etaxonomy.taxeditor.cdmlib/src/main/resources/eu/etaxonomy/cdm/localApplicationContext.xml
13 13
    <property name="omit" value="false" />
14 14
  </bean>
15 15
  
16
  
17
  
16 18
  <bean id="cdmEntitySessionManager" class="eu.etaxonomy.taxeditor.session.CdmEntitySessionManager" />
17 19
  
18 20
  <import resource="classpath:/eu/etaxonomy/cdm/remote.xml" />

Also available in: Unified diff