[ 
https://issues.apache.org/jira/browse/CAMEL-5719?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14233431#comment-14233431
 ] 

Ioannis Alexandrakis edited comment on CAMEL-5719 at 12/4/14 9:04 AM:
----------------------------------------------------------------------

I wanted the same thing; having a single instance running from the creation of 
the camel context. The way the policy currently works is that it "waits" for 
the first exchange  to stop the consumers from processing. It might be useful 
if the exchange is expendable (e.g. route is a *file* component or something of 
the sort). If it is not, (e.g. a *jetty* or an *activemq* component), it would 
mean that the +first exchange (if it happens to arrive on a 'secondary' camel 
route) would be 'lost'+ and if it hasn't been thought through, it might mean 
problems in the application.

The most useful approach would be to not start the route on the onInit phase. 
However, there are some inherent problems (for example, the context is not yet 
fully started between all those phases and I think you can't mark a route as 
autoStartup = false in any of the RoutePolicy's methods, it won't work, and the 
context is not yet fully initialized). Moreover, the component itself 'injects' 
another route (election-route-XXXXXXXX) in the camel context itself, which 
makes the things even more complicated.

One way would be to setAutoStartup(false) in the camel context containing the 
routes. However, if you have routes that you don't want to be suspended from 
the beginning, this would create problems. This would not start the injected 
election route from the above paragraph too. And you can't get a callback 
(apart from the StartupListener interface, I couldn't find anything else that 
could help).

h5. In the end, I managed to get the expected behaviour by doing the following:
*1)* Created a new camel context (this could be static, for performance 
reasons, but I do not think it has a large overhead), in which I put the 
election route, just to be easily manageable, and to distinguish it from the 
others. This has the downside that you have to manually start/stop it (however 
I think it is not a problem, I close it overriding the +doShutdown()+).
*2)* For each route, overrode the +onStart(Route route)+ and check whether the 
node +isMaster+. If it is not, stop its consumers (this way, it doesn't get to 
process anything yet, and we assume it is 'paused'). We might be able to avoid 
the step above with the new camel context, if we make sure that the 
+onStart(Route route)+ is not run for the election route (because it would 
create a deadlock). However, I like the idea of the election route being 
separate (in karaf the route was appearing when I was scanning the camel 
contexts. When it was alone, it was 'hidden')


So, having those modifications, we get the benefit of having the route without 
consumers if it is not a primary node on startup, however on any election 
change, the consumer(s) will be started.

I tested it within karaf, and the behaviour was what I expected, single 
instance of a route running at all times.
(+the attached patch is from 2.14.1-SNAPSHOT+)

Note: after these checks, I think the +onExchangeBegin(Route route, Exchange 
exchange)+ does not need the check the election. However, I did not modify 
anything there, just for safety.


was (Author: ialex):
I wanted the same thing; having a single instance running from the creation of 
the camel context. The way the policy currently works is that it "waits" for 
the first exchange  to stop the consumers from processing. It might be useful 
if the exchange is expendable (e.g. route is a *file* component or something of 
the sort). If it is not, (e.g. a *jetty* or an *activemq* component), it would 
mean that the +first exchange (if it happens to arrive on a 'secondary' camel 
route) would be 'lost'+ and if it hasn't been thought through, it might mean 
problems in the application.

The most useful approach would be to not start the route on the onInit phase. 
However, there are some inherent problems (for example, the context is not yet 
fully started between all those phases and there is no easy way to stop the 
route while the context is not yet fully initialized). Moreover, the component 
itself 'injects' another route (election-route-XXXXXXXX) in the camel context 
itself, which makes the things even more complicated.

One way would be to setAutoStartup(false) in the camel context containing the 
routes. However, if you have routes that you don't want to be suspended from 
the beginning, this would create problems. This would not start the injected 
election route from the above paragraph too. And, finally, things get 
complicated if you try to start/stop routes before the context is fully 
started. And you can't get a callback (apart from the StartupListener 
interface, I couldn't find anything else that could help).

h5. In the end, I managed to get the expected behaviour by doing the following:
*1)* Created a new camel context (this could be static, for performance 
reasons, but I do not think it has a large overhead), in which I put the 
election route, just to be easily manageable, and to distinguish it from the 
others. This has the downside that you have to manually start/stop it (however 
I think it is not a problem, I close it overriding the +doShutdown()+).
*2)* For each route, overrode the +onStart(Route route)+ and check whether the 
node +isMaster+. If it is not, stop its consumers (this way, it doesn't get to 
process anything yet, and we assume it is 'paused'). We might be able to avoid 
the step above with the new camel context, if we make sure that the 
+onStart(Route route)+ is not run for the election route (because it would 
create a deadlock). However, I like the idea of the election route being 
separate (in karaf the route was appearing when I was scanning the camel 
contexts. When it was alone, it was 'hidden')


So, having those modifications, we get the benefit of having the route without 
consumers if it is not a primary node on startup, however on any election 
change, the consumer(s) will be started.

I tested it within karaf, and the behaviour was what I expected, single 
instance of a route running at all times.
(+the attached patch is from 2.14.1-SNAPSHOT+)

Note: after these checks, I think the +onExchangeBegin(Route route, Exchange 
exchange)+ does not need the check the election. However, I did not modify 
anything there, just for safety.

> ZooKeeper route policy should initialize using onInit to elect master
> ---------------------------------------------------------------------
>
>                 Key: CAMEL-5719
>                 URL: https://issues.apache.org/jira/browse/CAMEL-5719
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-zookeeper
>    Affects Versions: 2.10.0
>            Reporter: Claus Ibsen
>             Fix For: Future
>
>         Attachments: zookeeper-election.patch
>
>
> See nabble
> http://camel.465427.n5.nabble.com/Single-instance-of-running-route-in-the-cluster-tp5720846.html



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

Reply via email to