You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (JIRA)" <ji...@apache.org> on 2018/01/10 14:03:00 UTC
[jira] [Resolved] (CAMEL-12131) CacheProducer should not put
services in Camel context, that are not singletons and are not
ServicePoolAware
[ https://issues.apache.org/jira/browse/CAMEL-12131?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Claus Ibsen resolved CAMEL-12131.
---------------------------------
Resolution: Fixed
> CacheProducer should not put services in Camel context, that are not singletons and are not ServicePoolAware
> ------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-12131
> URL: https://issues.apache.org/jira/browse/CAMEL-12131
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: Rafał Gała
> Assignee: Claus Ibsen
> Priority: Minor
> Fix For: 2.19.5, 2.20.2, 2.21.0
>
>
> When the org.apache.camel.impl.ProducerCache *doGetProducer* method is called from *org.apache.camel.processor.SendProcessor's doStart()* method, it will create new instance of a Producer, and put it into Camel context by calling *getCamelContext().addService(answer, false);*. However, it will not put the object into producers or the pool map, because it is not ServicePoolAware and is not a singleton. This results in a service that will later be started by *DeferServiceStartupListener* and will stay started until the whole context is closed.
> {code:java}
> protected synchronized Producer doGetProducer(Endpoint endpoint, boolean pooled) {
> String key = endpoint.getEndpointUri();
> Producer answer = producers.get(key);
> if (pooled && answer == null) {
> // try acquire from connection pool
> answer = pool.acquire(endpoint);
> }
> if (answer == null) {
> // create a new producer
> try {
> answer = endpoint.createProducer();
> // add as service which will also start the service
> // (false => we and handling the lifecycle of the producer in this cache)
> getCamelContext().addService(answer, false);
> } catch (Throwable e) {
> throw new FailedToCreateProducerException(endpoint, e);
> }
> // add producer to cache or pool if applicable
> if (pooled && answer instanceof ServicePoolAware) {
> LOG.debug("Adding to producer service pool with key: {} for producer: {}", endpoint, answer);
> answer = pool.addAndAcquire(endpoint, answer);
> } else if (answer.isSingleton()) {
> LOG.debug("Adding to producer cache with key: {} for producer: {}", endpoint, answer);
> producers.put(key, answer);
> }
> }
> if (answer != null) {
> // record statistics
> if (extendedStatistics) {
> statistics.onHit(key);
> }
> }
> return answer;
> }
> {code}
> Here is the part of *doStart()* method from *SendProcessor* class. The producer is acquired and after that is immediately released in *ProducerCache*, however it is not removed from Camel context and stays there as a Service and will later by started by *DeferServiceStartupListener*
> {code:java}
> Producer producer = producerCache.acquireProducer(destination);
> if (producer instanceof ServicePoolAware || !producer.isSingleton()) {
> // no we cannot optimize it - so release the producer back to the producer cache
> // and use the producer cache for sending
> producerCache.releaseProducer(destination, producer);
> } else {
> // yes we can optimize and use the producer directly for sending
> this.producer = AsyncProcessorConverterHelper.convert(producer);
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)