Daly, Paul
2018-04-25 08:12:20 UTC
Hi All,
First time poster, hoping you can provide some advice/help!
WE have developed a connector to a back end server using HTTP Client. The component with the HTTPClient runs as part of, and is used by, a larger application - ie not a standalone application which we have control to completely change. As per performance optimisations guide I reuse the HTTPClient object within this communication component. Its's initialised on first use and within the running application, the httpClient object will be passed out to multiple threads who each will execute their own particular request to the back end. Request objects are reset() by the thread which used them.
So far so good. All seems to work ok.
However, the application we are running within provides a front end for users. For admins, this allows changing of various configuration items, some of which are the timeouts for this component. If an admin changes those values we want to be able to change the HTTPClient to use the new values without a restart of the application. The application framework provides an annotation I can use in my class to pick up config change events. I can react on that to refresh my timeout values and recreate the client.
This is where my question starts. My solution so far is to simply replace the static httpClient with the newly build object which has the new timeout values. But this may lead to problems because I am not sure if the original object will actually be tidied up by GC once the threads using it have closed their connections.
Ideally I would want to explicitly close the original httpClient before pointing the static at the new one. However, this means threads which have already been handed this httpClient reference will fail (user impact - not acceptable).
So I am kind of stuck on how to implement this safely
Ideally I could just change the configured timeouts in the existing httpClient but I don't see how to do that.
Code snippets are below.
Any ideas / suggestions would be appreciated!
/**
* A HTTP Client to be used by the EIS PH
*/
private static CloseableHttpClient httpClient = null;
// get client
public static CloseableHttpClient getClient() {
if (httpClient == null) {
// create new client
init(false);
}
return httpClient;
}
// initialize the client
private static synchronized void init(boolean forceNewClient) {
if (forceNewClient || (httpClient == null)) {
// get config, timeouts etc from application framework...
.....
// create the client
CloseableHttpClient newClient = HttpClientBuilder.create().useSystemProperties()
.setDefaultRequestConfig(config).setMaxConnPerRoute(maxConnectionsPerRoute)
.setMaxConnTotal(totalMaxConnection).evictExpiredConnections()
.evictIdleConnections(idleEvictTime, TimeUnit.MINUTES)
.setConnectionTimeToLive(timeToLive, TimeUnit.MINUTES).build();
// set the static member to be the new client now that its built
httpClient = newClient;
}
// listen for application config change events which affect this component
@ConfigChangedListener(ConfigurationHelper.OWNER)
public void onConfigChanged() {
init(true);
}
Thanks in advance!
Paul.
Paul Daly
Diebold Nixdorf
3022 Lake Drive,
Citywest Business Park,
Dublin 24,
Ireland
Mobile: +353 87 276 4736
***@dieboldnixdorf.com<mailto:***@dieboldnixdorf.com>
DieboldNixdorf.com
[1_twitter_logo_24px]<https://twitter.com/DieboldNixdorf> [2_facebook_logo_24px] <https://www.facebook.com/DieboldNixdorf> [3_youtube_logo_24px] <https://www.youtube.com/DieboldNixdorf> [4_linkedin_logo_24px] <https://www.linkedin.com/company/diebold> [5_blog_logo_24px] <http://blog.dieboldnixdorf.com/>
Reg. in England No. 3841833
This document and any attachments to it contain information that is private and confidential and should only be read by those persons to whom they are addressed. No person, without subsequent written confirmation of their contents, should rely upon the contents of this e-mail. This e-mail and the information it contains are supplied in good faith, but Diebold Nixdorf (Ireland) Limited shall not be under any liability in damages or otherwise for any reliance that may be placed upon them by the recipient. Further, this document is sent for information and / or negotiating purposes only, and shall not have the effect of creating a contract between the parties. If you have received this e-mail in error, please notify the sender(s) immediately by telephone. Please also destroy and delete the message from your computer. Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of this e-mail is strictly prohibited save unless expressly authorised by the sender
First time poster, hoping you can provide some advice/help!
WE have developed a connector to a back end server using HTTP Client. The component with the HTTPClient runs as part of, and is used by, a larger application - ie not a standalone application which we have control to completely change. As per performance optimisations guide I reuse the HTTPClient object within this communication component. Its's initialised on first use and within the running application, the httpClient object will be passed out to multiple threads who each will execute their own particular request to the back end. Request objects are reset() by the thread which used them.
So far so good. All seems to work ok.
However, the application we are running within provides a front end for users. For admins, this allows changing of various configuration items, some of which are the timeouts for this component. If an admin changes those values we want to be able to change the HTTPClient to use the new values without a restart of the application. The application framework provides an annotation I can use in my class to pick up config change events. I can react on that to refresh my timeout values and recreate the client.
This is where my question starts. My solution so far is to simply replace the static httpClient with the newly build object which has the new timeout values. But this may lead to problems because I am not sure if the original object will actually be tidied up by GC once the threads using it have closed their connections.
Ideally I would want to explicitly close the original httpClient before pointing the static at the new one. However, this means threads which have already been handed this httpClient reference will fail (user impact - not acceptable).
So I am kind of stuck on how to implement this safely
Ideally I could just change the configured timeouts in the existing httpClient but I don't see how to do that.
Code snippets are below.
Any ideas / suggestions would be appreciated!
/**
* A HTTP Client to be used by the EIS PH
*/
private static CloseableHttpClient httpClient = null;
// get client
public static CloseableHttpClient getClient() {
if (httpClient == null) {
// create new client
init(false);
}
return httpClient;
}
// initialize the client
private static synchronized void init(boolean forceNewClient) {
if (forceNewClient || (httpClient == null)) {
// get config, timeouts etc from application framework...
.....
// create the client
CloseableHttpClient newClient = HttpClientBuilder.create().useSystemProperties()
.setDefaultRequestConfig(config).setMaxConnPerRoute(maxConnectionsPerRoute)
.setMaxConnTotal(totalMaxConnection).evictExpiredConnections()
.evictIdleConnections(idleEvictTime, TimeUnit.MINUTES)
.setConnectionTimeToLive(timeToLive, TimeUnit.MINUTES).build();
// set the static member to be the new client now that its built
httpClient = newClient;
}
// listen for application config change events which affect this component
@ConfigChangedListener(ConfigurationHelper.OWNER)
public void onConfigChanged() {
init(true);
}
Thanks in advance!
Paul.
Paul Daly
Diebold Nixdorf
3022 Lake Drive,
Citywest Business Park,
Dublin 24,
Ireland
Mobile: +353 87 276 4736
***@dieboldnixdorf.com<mailto:***@dieboldnixdorf.com>
DieboldNixdorf.com
[1_twitter_logo_24px]<https://twitter.com/DieboldNixdorf> [2_facebook_logo_24px] <https://www.facebook.com/DieboldNixdorf> [3_youtube_logo_24px] <https://www.youtube.com/DieboldNixdorf> [4_linkedin_logo_24px] <https://www.linkedin.com/company/diebold> [5_blog_logo_24px] <http://blog.dieboldnixdorf.com/>
Reg. in England No. 3841833
This document and any attachments to it contain information that is private and confidential and should only be read by those persons to whom they are addressed. No person, without subsequent written confirmation of their contents, should rely upon the contents of this e-mail. This e-mail and the information it contains are supplied in good faith, but Diebold Nixdorf (Ireland) Limited shall not be under any liability in damages or otherwise for any reliance that may be placed upon them by the recipient. Further, this document is sent for information and / or negotiating purposes only, and shall not have the effect of creating a contract between the parties. If you have received this e-mail in error, please notify the sender(s) immediately by telephone. Please also destroy and delete the message from your computer. Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of this e-mail is strictly prohibited save unless expressly authorised by the sender