0

This is my route

from("myComponent:entity?from=&to=")
.to("seda:one")

from("seda:one")
.
.
to("seda:two")

.
.
.


from("seda:five")
.to("myComponent2:entity")

The flow from 'seda:one' to 'seda:two' is pretty quick and completes way before the other routes. But even though I kill the particular route, I can still see parked threads when inspecting with visual VM. My use case is based on dynamic queues, and I plan to run n number of the same routes parallely with different seda queues. Can someone help me on explaining what this parked thread is, and how I can shutdown the route/queues in the component as soon as I'm done with it. I have referred to a lot of articles, and I feel that I might be missing something very trivial. Any help would be greatly appreciated.

In Visual VM, after my process is over, I can still see parked threads for every seda I have used in my route.

This is the relevant part of the thread dump


"Camel (camel-1) thread #7 - seda://one" #53 daemon prio=5 os_prio=31 tid=0x00007fa8b389c800 nid=0x8003 waiting on condition [0x0000700007be3000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006c0678348> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:176)
        at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:130)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x00000006c0678460> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"Camel (camel-1) thread #6 - seda://two" #52 daemon prio=5 os_prio=31 tid=0x00007fa8b016c800 nid=0x8203 waiting on condition [0x0000700007ae0000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006c07d2090> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:176)
        at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:130)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x00000006c0770e10> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"Camel (camel-1) thread #5 - seda://three" #51 daemon prio=5 os_prio=31 tid=0x00007fa8ada31800 nid=0x8303 waiting on condition [0x00007000079dd000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006c0639cc0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:176)
        at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:130)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x00000006c0639dd8> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"Camel (camel-1) thread #4 - seda://four" #50 daemon prio=5 os_prio=31 tid=0x00007fa8ae2a9800 nid=0x8403 waiting on condition [0x00007000078da000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006c06d7c50> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:176)
        at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:130)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x00000006c06d7d68> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"Camel (camel-1) thread #3 - myComponent2:entity" #49 daemon prio=5 os_prio=31 tid=0x00007fa8b1184800 nid=0x7803 waiting on condition [0x00007000077d7000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006c06dcba8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"Camel (camel-1) thread #2 - seda://new_test" #48 daemon prio=5 os_prio=31 tid=0x00007fa8b4d23800 nid=0x8703 waiting on condition [0x00007000076d4000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006c06dd560> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:176)
        at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:130)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x00000006c06dd678> (a java.util.concurrent.ThreadPoolExecutor$Worker)
Shark Man
  • 21
  • 2
  • In Camel is nothing like "kill" the route - there is `stop` and `suspend`. Please share the code where you think you are killing the route to make clear what you are actually doing. The `stop` destroys `ExecutorService`, so there should be no remaining seda threads if used correctly. Also if you need for some reason to dynamically create many short lived seda queues, then it is probably design flaw, which can be achieved much better with different EIP. – Bedla Sep 13 '20 at 21:22
  • `I plan to run n number of the same routes parallely with different seda queues` Notice that the Camel Seda component has an option `concurrentConsumers` so you don't need to run multiple instances of the same route by yourself. – burki Sep 14 '20 at 05:11
  • @Bedla I stop the route using `.to("controlbus:route?routeId=test_1&action=stop")`. Also, one point where I'm confused is what is the lifecycle of my seda queue. Is there any documentation for when/how a component/route shuts down. I cannot find any extensive documentation for my use case. – Shark Man Sep 14 '20 at 06:58
  • @burki my use case is such that, we can consider it as a part of a multi tenant system. My understanding is that a CamelContext will start along with my server, and end when my server ends. A request can trigger for a particular tenant and the routes will run for the components with the tenant's auth, where data will flow through the components for tenant-specific seda queues. I want the routes/queues to end after the process is done. An other tenant can also run the same routes for his own auth. Please advice if my approach might be wrong, and is there any better way to handle this pattern? – Shark Man Sep 14 '20 at 07:01
  • Also, in particular my custom component uses an executor to send data using `getAsyncProcessor().process(exchange, callback)` . After my component is done sending data, it is still in started state. Is there any way I can shutdown the component after I have pushed all the data I need to. That might be the starting point for why the queue is not shutting down. For reference this is how my component internally looks like https://stackoverflow.com/questions/63858617/asynchronous-camel-component-dostop-called-immediately . Any help would be greatly appreciated. – Shark Man Sep 14 '20 at 07:09
  • OK, I see your point with multi tenancy, this is absolutely fine. I thought you want to scale by multiplying the same route instead of increasing the consumer count. – burki Sep 14 '20 at 07:50
  • For the shutdown problem: Camel routes are by default running all the time. When you shut them down, you should be fine and you can restart them later. The method `getRouteStatus` tells you the route state from Camels point of view. Route shutdown can be delayed to allow running Exchanges to complete – burki Sep 14 '20 at 08:02
  • @burki Do you advice m camel contexts with n routes or 1 camel context with m x n, routes having startup and shutdown co-inciding with that of my server ? Can I have any examples if available for my pattern ? – Shark Man Sep 14 '20 at 12:15
  • Notice that since Camel 3.x multiple Camel Contexts are no more supported in a single application. See here: https://camel.apache.org/manual/latest/camel-3-migration-guide.html#_multiple_camelcontexts_per_application_not_supported – burki Sep 14 '20 at 15:00
  • It seemed to work fine when I deployed it as a standalone code in the server. But yes, I think I will prefer the single camel context route. Any idea on how to finish my consumer when all my data has been pushed out ? I figure there must be some way to manually shutdown my consumer from inside the `process()` part of the consumer itself ? – Shark Man Sep 15 '20 at 05:19
  • * the `getAsyncProcessor.process()` inside the consumer runs on a separate executor thread inside the consumer though. – Shark Man Sep 15 '20 at 06:17
  • Adding as a separate question. – Shark Man Sep 16 '20 at 04:58
  • @SharkMan did you find solution for this problem. Even i am facing same issue now – mahi244 Jun 16 '23 at 17:38

0 Answers0