[ 
https://issues.apache.org/jira/browse/CXF-6513?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Mike updated CXF-6513:
----------------------
    Description: 
I encountered strange behaviour with using async WebClient. For case of example 
I create JAXRSClientFactoryBean with failover strategy:

{noformat}
    FailoverFeature feature = new FailoverFeature();
    feature.setTargetSelector(new LoadDistributorTargetSelector());

    List<String> alternateAddresses = new ArrayList<String>();
    // addresses are alternate addresses provided at start-up
    alternateAddresses.add("http://localhost:1234";);
    alternateAddresses.add("http://localhost:5678";);

    SequentialStrategy strategy = new SequentialStrategy();
    strategy.setAlternateAddresses(alternateAddresses);
    feature.setStrategy(strategy);

    JAXRSClientFactoryBean factoryBean = new JAXRSClientFactoryBean();
    factoryBean.setAddress("http://localhost:1234";); // setting initial address

    LoadDistributorTargetSelector targetSelector = new 
LoadDistributorTargetSelector();
    targetSelector.setStrategy(strategy);
    factoryBean.setConduitSelector(targetSelector);

    factoryBean.setServiceClass(SomeService.class);
    List<Feature> features = new ArrayList<Feature>();
    features.add(feature);
    factoryBean.setFeatures(features);

    WebClient webClient = factoryBean.createWebClient();
{noformat}

Next I am making invocation of my request:

{noformat}
Future<Response> post = 
webClient.path("service/path").async().post(Entity.json(request));

{noformat}

After running about 200~300 requests I observed huge memory usage of my 
component. Made heapdump and investigated that 
org.apache.cxf.clustering.LoadDistributorTargetSelector is keeping much data in 
ConcurrentHashMap (and this data is never released in case os AsyncInvoker):

{noformat}
protected ConcurrentHashMap<InvocationKey, InvocationContext> inProgress 
    = new ConcurrentHashMap<InvocationKey, InvocationContext>();

 public void prepare(Message message) {
    ...
    inProgress.putIfAbsent(key, invocation);
 }
{noformat}

Everything would be fine if that map was cleared after the request but in case 
of AsyncInvoker it is not and quickly leads to OutOfMemoryError. In SyncInvoker 
map is being cleared by FailoverTargetSelector class:

{noformat}
public void complete(Exchange exchange) {
...
if (!failover) {
        inProgress.remove(key);
        doComplete(exchange);
    }
{noformat}

Any ideas is it indeed a bug ? Or I am missing something.

  was:
I encountered strange behaviour with using async WebClient. For case of example 
I create JAXRSClientFactoryBean with failover strategy:

{noformat}
FailoverFeature feature = new FailoverFeature();
    feature.setTargetSelector(new LoadDistributorTargetSelector());

    List<String> alternateAddresses = new ArrayList<String>();
    // addresses are alternate addresses provided at start-up
    alternateAddresses.add("http://localhost:1234";);
    alternateAddresses.add("http://localhost:5678";);

    SequentialStrategy strategy = new SequentialStrategy();
    strategy.setAlternateAddresses(alternateAddresses);
    feature.setStrategy(strategy);

    JAXRSClientFactoryBean factoryBean = new JAXRSClientFactoryBean();
    factoryBean.setAddress("http://localhost:1234";); // setting initial address

    LoadDistributorTargetSelector targetSelector = new 
LoadDistributorTargetSelector();
    targetSelector.setStrategy(strategy);
    factoryBean.setConduitSelector(targetSelector);

    factoryBean.setServiceClass(SomeService.class);
    List<Feature> features = new ArrayList<Feature>();
    features.add(feature);
    factoryBean.setFeatures(features);

    WebClient webClient = factoryBean.createWebClient();
{noformat}

Next I am making invocation of my request:

{noformat}
Future<Response> post = 
webClient.path("service/path").async().post(Entity.json(request));

{noformat}

After running about 200~300 requests I observed huge memory usage of my 
component. Made heapdump and investigated that 
org.apache.cxf.clustering.LoadDistributorTargetSelector is keeping much data in 
ConcurrentHashMap (and this data is never released in case os AsyncInvoker):

{noformat}
protected ConcurrentHashMap<InvocationKey, InvocationContext> inProgress 
    = new ConcurrentHashMap<InvocationKey, InvocationContext>();

 public void prepare(Message message) {
    ...
    inProgress.putIfAbsent(key, invocation);
 }
{noformat}

Everything would be fine if that map was cleared after the request but in case 
of AsyncInvoker it is not and quickly leads to OutOfMemoryError. In SyncInvoker 
map is being cleared by FailoverTargetSelector class:

{noformat}
public void complete(Exchange exchange) {
...
if (!failover) {
        inProgress.remove(key);
        doComplete(exchange);
    }
{noformat}

Any ideas is it indeed a bug ? Or I am missing something.


> CXF Using async WebClient with load distribution failover strategy leads to 
> memory leak
> ---------------------------------------------------------------------------------------
>
>                 Key: CXF-6513
>                 URL: https://issues.apache.org/jira/browse/CXF-6513
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.0.1
>            Reporter: Mike
>
> I encountered strange behaviour with using async WebClient. For case of 
> example I create JAXRSClientFactoryBean with failover strategy:
> {noformat}
>     FailoverFeature feature = new FailoverFeature();
>     feature.setTargetSelector(new LoadDistributorTargetSelector());
>     List<String> alternateAddresses = new ArrayList<String>();
>     // addresses are alternate addresses provided at start-up
>     alternateAddresses.add("http://localhost:1234";);
>     alternateAddresses.add("http://localhost:5678";);
>     SequentialStrategy strategy = new SequentialStrategy();
>     strategy.setAlternateAddresses(alternateAddresses);
>     feature.setStrategy(strategy);
>     JAXRSClientFactoryBean factoryBean = new JAXRSClientFactoryBean();
>     factoryBean.setAddress("http://localhost:1234";); // setting initial 
> address
>     LoadDistributorTargetSelector targetSelector = new 
> LoadDistributorTargetSelector();
>     targetSelector.setStrategy(strategy);
>     factoryBean.setConduitSelector(targetSelector);
>     factoryBean.setServiceClass(SomeService.class);
>     List<Feature> features = new ArrayList<Feature>();
>     features.add(feature);
>     factoryBean.setFeatures(features);
>     WebClient webClient = factoryBean.createWebClient();
> {noformat}
> Next I am making invocation of my request:
> {noformat}
> Future<Response> post = 
> webClient.path("service/path").async().post(Entity.json(request));
> {noformat}
> After running about 200~300 requests I observed huge memory usage of my 
> component. Made heapdump and investigated that 
> org.apache.cxf.clustering.LoadDistributorTargetSelector is keeping much data 
> in ConcurrentHashMap (and this data is never released in case os 
> AsyncInvoker):
> {noformat}
> protected ConcurrentHashMap<InvocationKey, InvocationContext> inProgress 
>     = new ConcurrentHashMap<InvocationKey, InvocationContext>();
>  public void prepare(Message message) {
>     ...
>     inProgress.putIfAbsent(key, invocation);
>  }
> {noformat}
> Everything would be fine if that map was cleared after the request but in 
> case of AsyncInvoker it is not and quickly leads to OutOfMemoryError. In 
> SyncInvoker map is being cleared by FailoverTargetSelector class:
> {noformat}
> public void complete(Exchange exchange) {
> ...
> if (!failover) {
>         inProgress.remove(key);
>         doComplete(exchange);
>     }
> {noformat}
> Any ideas is it indeed a bug ? Or I am missing something.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to