Camel recipientList: How to prevent leaking of threads - apache-camel

I have a route like the following to a dynamic computed HTTP URL:
from("file:in")
.recipientList(simple(jettyUrl + "?id=${exchangeId}"))
.to("file:out?fileName=abc");
as it is described in the FAQ:
http://camel.apache.org/how-do-i-use-dynamic-uri-in-to.html
Each time an exchange is processed a new jetty component with a new threadpool is created. The threadpool is newer released. After a couple of exchanges the threads are exhausted.
I'am using Camel 2.12.2. In that version it is not possible anymore to set an httpClient instance or an executor to the jetty component to prevent the leak. The options httpClientThreadPool and httpClient that would be useful have been removed in camel 2.11.
How can I request an HTTP Url containing query parameters without leaking threads.
Maybe my approach is wrong and somebody can point me in the right direction.

My approach was wrong. By using an HTTP_QUERY or HTTP_URI header the recipientList is not needed anymore and only one endpoint is created. As a result there is no thread leak anymore.
.setHeader(Exchange.HTTP_URI, simple("http://somehost3244.org/id=${exchangeId}"))
.to("jetty:http://dummyhost243242.org")

Related

Reusing Apache Camel route and avoiding sleeping the thread

I am working on a project where I am using Apache Camel to establish a connection to a URL using Java code in a method:
public void establishConnection()
{
final CamelContext context = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder(){//logic});
camelContext.start();
Thread.sleep(7500);
camelContext.stop();
}
The issue is that it is necessary to pause the thread, otherwise the following code executes, so to wait for the response as it takes camel time to start.
Now the issue is if this method gets called many times and I want the camel context to be initialized once only with the route so that we dont have to use the sleep here for subsequent calls.
What context are you in? You don't need to do the work to start/stop by yourself (as Adam also commented), Camel does it for you.
When you are building a Spring Boot application, check out how to use Camel with Spring Boot.
When you use Camel standalone, have a look at this example.

pollEnrich with dynamic URI and its number of executions

I want to listen on ActiveMQ topic based on the hostname of system and some other logic. I planned to use pollEnrich for it so I evaluate my logic and provide topic name in pollEnrich but as per document:
pollEnrich or enrich does not access any data from the current Exchange which means when polling it cannot use any of the existing headers you may have set on the Exchange. For example you cannot set a filename in the Exchange.FILE_NAME header and use pollEnrich to consume only that file. For that you must set the filename in the endpoint URI.
How i can figure out this
from("timer://ipc?repeatCount=1")
.. some logic..
.setHeader("topic_no",simple("{{env:HOSTNAME}}"))
.pollEnrich("mqtt:foo?host=tcp://0.0.0.0:1883&subscribeTopicNames=${header.topic_no}/status&clientId=ipc")
.to("log:my?showAll=true&multiline=true");
Please don't suggest to use hostname directly in URI. As I highlighted I have to compute other logic too.
What other option or way I can use?
Will pollEnrich kept listening on topic or it will listen once and end the route?
Update1:
I figured out we can use simple expression with for dynamic URI, But one issue with pollEnrich it only pick one message how i can make sure it kept on listening as consumer? I want that before pollEnrich part get execute once and TopicListener kept listening till application is up.
Will pollEnrich kept listening on topic or it will listen once and end the route?
Same as the fact you have figure out, Camel pollEnrich component will listen on topic and consume at most one message per call.
What other option or way I can use?
Repeat pollEnrich by loop
Create new route at run-time by routeBuilder
Option 1 is naive, but simple in concept. pollEnrich will do once and loop will repeat it. However, this method need to handle more scenario than you might expected.
Option 2 is a better approach. You create a route at run-time and the consumer endpoint URI is pass by variable. That said, you can create the consumer route dynamically after your computation logic.
Example for routeBuilder

Updating database in different thread in camel based application

I have a Camel based application which receives a request and gives the reply from cache but in between this process it updates the database which i want it to run in a different thread , can anyone tell me how can i achieve this, i tried with WireTap and SEDA but it does not work that way...any help appreciated.
<camel:wireTap uri="seda:tap" processorRef="updateHitCountProcessor"/>
In updateHitCountProcessor I have written code to update table
it is updating the database in same thread (i.e main route thread)
You need to do
<camel:wireTap uri="ref:updateHitCountProcessor"/>
The processorRef attribute is creating and sending a new message, and not for tapping the existing message. So you should not use that.
The uri is used for sending the message which happens in a separate thread. So when you send it to the ref endpoint it will do that in another thread, and call your processor.
You can find details on the wire tap page at: http://camel.apache.org/wire-tap
From the documentation of the camel-seda component (here):
By default, the SEDA endpoint uses a single consumer thread, but you
can configure it to use concurrent consumer threads.
You can add a thread pool to a SEDA endpoint like this:
<from uri="seda:stageName?concurrentConsumers=5" />

Apache Camel slow startup of routes

I am using Apache camel to implement dispatcher EIP. There are thousands of messages in a queue which needs to be delivered at different URLs. Each message has its own delivery URL and delivery protocol (ftp,email,http etc).
The way it is been implemented:
Boot a single camel context, the context is disabled for JMX and the
loadStatisticsEnabled is set to false on the ManagementStrategy. As
mentioned in a jira issue, addressed in 2.11.0 version, for disabling
the background management thread creation.
For each message a route is being constructed , the message is being
pushed to the route for delivery.
After the message is processed route is shutdown and removed from
context.
Did a small perf test by having 200 threads of dispatcher component, each sharing the same context.
Observed that the time to start a route increases upto a maximum of 60 seconds while the time to process is in milliseconds.
Issue CAMEL-5675 mentions that this has been fixed but still observing significant time being taken in starting up routes.
https://issues.apache.org/jira/browse/CAMEL-5675
The route that is being creating for http is
from("direct:"+dispatchItem.getID())
.toF("%s?httpClient.soTimeout=%s&disableStreamCache=true", dispatchItem.getEndPointURL(),timeOutInMillis);
Each dispatchItem has a unique ID.
This is being active discussed elsewhere, where the user posted this question first: http://camel.465427.n5.nabble.com/Slow-startup-of-routes-tp5732356.html

Cannot create Timer class in backend AppEngine instance...why?

I am able to create threads however creation of a Timer and scheduling it are eluding me. I am unsure why this is failing...and silently!
Any ideas?
You can use threads in GAE, but there are limitations:
You must create them via GAE provided ThreadManager.
On frontend instances threads can not outlive requests. This means that Timer started from a http request can not run TimerTask if the request already ended - I guess this is why it silently fails.
If you need to start a delayed task, try using DeferredTask (here's an example) with ETA setting.

Resources